RubenFelix Posted February 8, 2013 at 10:41 AM Report #494593 Posted February 8, 2013 at 10:41 AM (edited) Olá pessoal, Tenho aqui uma duvida e gostaria de saber se alguém me pode ajudar: Tenho uma classe que será o meu login - A classe já está definida e desenhada e está tudo okey. Agora, o que eu queria fazer, era fazer o update desta interface através de uma outra classe auxiliar que criei com alguns métodos. O que acontece é que, quando a classe auxiliar tenta o update da UI (neste caso, seria meter todos os componentes de um JPanel disabled) ocorre uma situação estranha: Os componentes ficam disabled mas, se eu voltar a clicar com o rato nos textfield's, eles voltam a ficar enable. Classe LoginInterface: private void bt_LoginActionPerformed(java.awt.event.ActionEvent evt) { try { /** * Botão de teste */ EventQueue.invokeAndWait( new Runnable() { @Override public void run() { MainLoginAppAux.BlockAllComponents(pn_Login.getComponents()); } }); } catch (InterruptedException ex) { } catch (InvocationTargetException ex) { } } Classe MainLoginAppAux public static void BlockAllComponents(Component[] components) { //Percorre todos os componentes passados por parametro for (int i = 0; i < components.length; i++) { final Component a = components[i]; //Faz o set enable a false - disable a.setEnabled(false); } } Podem ajudar-me a perceber onde estou a falhar? Obrigado. Edited February 8, 2013 at 10:44 AM by RubenFelix
HappyHippyHippo Posted February 8, 2013 at 11:03 AM Report #494596 Posted February 8, 2013 at 11:03 AM dá uma olhada nisto, é o que necessitas para o teu problema : http://en.wikipedia.org/wiki/Observer_pattern IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
eatg75 Posted February 8, 2013 at 02:42 PM Report #494612 Posted February 8, 2013 at 02:42 PM dá uma olhada nisto, é o que necessitas para o teu problema : http://en.wikipedia.org/wiki/Observer_pattern Penso que o padrao de desenho Observer nao se aplica a esta situacao, as duas regras fortes para utilizar o padrao tal padrao e : a) temos uma relacao de um para muitos. b) precisamos de alterar o estado de um objecto a uma qualquer a altura durante o runtime. Apenas a alinea b) e que se verifica, o RubenFelix de acordo com a descricao do que ele pretende fazer (e pelo que percebi) nao diz que precisa adicionar/remover objectos para fazer o tracking do estado do outro em runtime. Victarion seized the dusky woman by the wrist and pulled her to him. Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see. Moqorro's dark eyes seemed to shine. Moqorro - I see dragons.
HappyHippyHippo Posted February 8, 2013 at 03:05 PM Report #494616 Posted February 8, 2013 at 03:05 PM 1-para-1 está englobado no 1-para-N 1 Report IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
RubenFelix Posted February 9, 2013 at 04:55 PM Author Report #494692 Posted February 9, 2013 at 04:55 PM (edited) Desde já, obrigado pelas vossas respostas. HappyHippyHippo, de facto o link ajudou-me a perceber alguns conceitos que terei que implementar na forma como vou desenhar a aplicação. De qualquer forma, ainda não consegui resolver o meu problema, mesmo implementando a arquitectura que me sugeriste. O que acontece, e não consigo perceber porque, é que a classe de View chama um método da classe Controller, passando por parametro os seus componentes visuais. A classe Controller faz o seu trabalho e define os componentes visuais com o .setEnable(false); mas, quando clico com o rato em cima do textfield que está supostamente disabled, ele volta a ficar enabled (ou seja, consigo novamente escrever nele e não seria suposto...). Em modo de debug, já verifiquei que os componentes visuais que pretendo desabilitar chegam à classe View com o enable = false. Não consigo perceber o que estou a fazer de errado. Deixo aqui o código destas duas classes para ver se alguém percebe onde estou a errar: Classe View: package View; import Controller.LoginController; import Logs.LoggerObject; import ViewAux.MainLoginAppAux; import java.awt.DisplayMode; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.util.Observable; import java.util.Observer; /** * Interface que servirá para o utilizador efectuar o login na aplicação * * @author Rúben Félix <Ruben.Felix@gmail.com> */ public class MainLoginApp extends javax.swing.JFrame implements Observer{ //Objecto que fará todo o logger aplicacional //public LoggerObject Logger = new LoggerObject(); //Objecto que fará todo o controlo a nivel de login da aplicação //private LoginController LoginContr = null; private MainLoginAppAux InterfaceAux = new MainLoginAppAux(); /** * Creates new form MainLoginApp */ public MainLoginApp() { this.InterfaceAux.addObserver(this); try { //Tenta retirar os Users da aplicação da base de dados //this.LoginContr = new LoginController(this.Logger); //Centrar a interface no centro do ecrã GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); DisplayMode dm = gs[0].getDisplayMode(); initComponents(); //O cursor começa logo apontado ao textfield de introdução do login this.tf_LoginUsername.requestFocusInWindow(); //Centra a frame this.setLocation((dm.getWidth()/2)-(this.getWidth()/2), (dm.getHeight()/2)-(this.getHeight()/2)); } catch (Exception ex) { //Caso não consiga retirar os users da base de dados, desabilita a interface do utilizador //this.InterfaceAux.BlockAllComponents(this.getComponents()); } initComponents(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { lbl_Titulo = new javax.swing.JLabel(); tb_LoginInterface = new javax.swing.JTabbedPane(); pn_Login = new javax.swing.JPanel(); lbl_LoginTitulo = new javax.swing.JLabel(); lbl_LoginDescr = new javax.swing.JLabel(); lbl_LoginUser = new javax.swing.JLabel(); lbl_LoginPass = new javax.swing.JLabel(); tf_LoginUsername = new javax.swing.JTextField(); tf_LoginPassword = new javax.swing.JPasswordField(); bt_Login = new javax.swing.JButton(); jButton1 = new javax.swing.JButton(); mb_MainMenu = new javax.swing.JMenuBar(); mn_File = new javax.swing.JMenu(); mi_Connect = new javax.swing.JMenuItem(); mi_Exit = new javax.swing.JMenuItem(); mn_Help = new javax.swing.JMenu(); mi_About = new javax.swing.JMenuItem(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Gestor Clientes - Login"); setResizable(false); lbl_Titulo.setFont(new java.awt.Font("Verdana", 1, 18)); // NOI18N lbl_Titulo.setForeground(new java.awt.Color(0, 102, 204)); lbl_Titulo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lbl_Titulo.setText("Gestor Clientes"); lbl_LoginTitulo.setFont(new java.awt.Font("Verdana", 1, 14)); // NOI18N lbl_LoginTitulo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); lbl_LoginTitulo.setText("Interface de Login"); lbl_LoginDescr.setFont(new java.awt.Font("Verdana", 0, 12)); // NOI18N lbl_LoginDescr.setText("Introduza as suas credênciais de acesso à aplicação:"); lbl_LoginUser.setFont(new java.awt.Font("Verdana", 0, 12)); // NOI18N lbl_LoginUser.setText("User:"); lbl_LoginPass.setFont(new java.awt.Font("Verdana", 0, 12)); // NOI18N lbl_LoginPass.setText("Pass:"); tf_LoginUsername.setFont(new java.awt.Font("Verdana", 0, 12)); // NOI18N tf_LoginUsername.setHorizontalAlignment(javax.swing.JTextField.CENTER); tf_LoginPassword.setFont(new java.awt.Font("Verdana", 0, 12)); // NOI18N tf_LoginPassword.setHorizontalAlignment(javax.swing.JTextField.CENTER); tf_LoginPassword.addKeyListener(new java.awt.event.KeyAdapter() { public void keyTyped(java.awt.event.KeyEvent evt) { tf_LoginPasswordKeyTyped(evt); } }); bt_Login.setText("Login"); bt_Login.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bt_LoginActionPerformed(evt); } }); jButton1.setText("jButton1"); jButton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); javax.swing.GroupLayout pn_LoginLayout = new javax.swing.GroupLayout(pn_Login); pn_Login.setLayout(pn_LoginLayout); pn_LoginLayout.setHorizontalGroup( pn_LoginLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pn_LoginLayout.createSequentialGroup() .addContainerGap() .addGroup(pn_LoginLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lbl_LoginTitulo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(lbl_LoginDescr, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE) .addGroup(pn_LoginLayout.createSequentialGroup() .addComponent(lbl_LoginPass) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tf_LoginPassword)) .addGroup(pn_LoginLayout.createSequentialGroup() .addComponent(lbl_LoginUser) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tf_LoginUsername)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pn_LoginLayout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(jButton1) .addGap(30, 30, 30) .addComponent(bt_Login))) .addContainerGap()) ); pn_LoginLayout.setVerticalGroup( pn_LoginLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(pn_LoginLayout.createSequentialGroup() .addComponent(lbl_LoginTitulo) .addGap(18, 18, 18) .addComponent(lbl_LoginDescr) .addGap(18, 18, 18) .addGroup(pn_LoginLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(lbl_LoginUser) .addComponent(tf_LoginUsername, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(pn_LoginLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lbl_LoginPass) .addComponent(tf_LoginPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(pn_LoginLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(bt_Login) .addComponent(jButton1)) .addGap(0, 15, Short.MAX_VALUE)) ); tb_LoginInterface.addTab("Login", pn_Login); mn_File.setText("Ficheiro"); mi_Connect.setText("Conectar"); mn_File.add(mi_Connect); mi_Exit.setText("Sair"); mi_Exit.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mi_ExitActionPerformed(evt); } }); mn_File.add(mi_Exit); mb_MainMenu.add(mn_File); mn_Help.setText("Ajuda"); mi_About.setText("Sobre"); mi_About.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { mi_AboutActionPerformed(evt); } }); mn_Help.add(mi_About); mb_MainMenu.add(mn_Help); setJMenuBar(mb_MainMenu); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(lbl_Titulo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(tb_LoginInterface)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(lbl_Titulo) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tb_LoginInterface) .addContainerGap()) ); pack(); }// </editor-fold> /** * Menu Item de exit * * @param evt */ private void mi_ExitActionPerformed(java.awt.event.ActionEvent evt) { this.Logger.Info(this, "Exiting app from menu item."); //Sai do programa System.exit(0); } /** * Menu Item de about * * @param evt */ private void mi_AboutActionPerformed(java.awt.event.ActionEvent evt) { //Abre uma nova frame de about //About about = new About(this); //Centra o about com as dimensões necessárias //about.setBounds(this.getX()+10, this.getY()+10,552, 290); //Frame a visible //about.setVisible(true); //about.setAlwaysOnTop(true); //A frame the login fica disabled //this.setEnabled(false); } /** * Método que permite a "escuta" do que está a ser escrito no tf da password * * @param evt */ private void tf_LoginPasswordKeyTyped(java.awt.event.KeyEvent evt) { /** * Metodo que permite a escuta do teclado do utilizador aquando da * introdução da password, esperando pela tecla enter para então dar * como introduzido as credencias de login e proceder então à sua * identificação */ int id = evt.getID(); int c = (int) evt.getKeyChar(); //Verifica se a tecla introduzida foi um enter if (c == 10) { //Confirma a tentativa de login this.bt_LoginActionPerformed(null); } } /** * Método que identifica a tentativa de login por parte de um utilizador * @param evt */ private void bt_LoginActionPerformed(java.awt.event.ActionEvent evt) { this.InterfaceAux.BlockAllComponents(this.pn_Login.getComponents()); } private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { System.out.println(""); } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(MainLoginApp.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(MainLoginApp.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(MainLoginApp.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(MainLoginApp.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MainLoginApp().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton bt_Login; private javax.swing.JButton jButton1; private javax.swing.JLabel lbl_LoginDescr; private javax.swing.JLabel lbl_LoginPass; private javax.swing.JLabel lbl_LoginTitulo; private javax.swing.JLabel lbl_LoginUser; private javax.swing.JLabel lbl_Titulo; private javax.swing.JMenuBar mb_MainMenu; private javax.swing.JMenuItem mi_About; private javax.swing.JMenuItem mi_Connect; private javax.swing.JMenuItem mi_Exit; private javax.swing.JMenu mn_File; private javax.swing.JMenu mn_Help; private javax.swing.JPanel pn_Login; private javax.swing.JTabbedPane tb_LoginInterface; private javax.swing.JPasswordField tf_LoginPassword; protected javax.swing.JTextField tf_LoginUsername; // End of variables declaration @Override public void update(Observable o, Object arg) { this.repaint(); this.doLayout(); System.out.println("Teste"); } } Classe Controller: package ViewAux; import java.awt.Component; import java.awt.EventQueue; import java.util.Observable; import javax.swing.SwingUtilities; /** * Classe que servirá de apoio à view MainLoginAppAux * * @author Rúben Félix <Ruben.Felix@gmail.com> */ public class MainLoginAppAux extends Observable{ /** * Método estático que permite que todos os componentes passados por * parametro sejam desabilitados da interface do utilizador * * @param components - Array de componentes a serem desabilitados */ public void BlockAllComponents(Component[] components) { //Percorre todos os componentes passados por parametro for (int i = 0; i < components.length; i++) { final Component a = components[i]; //Faz o set enable a false - disable EventQueue.invokeLater( new Runnable() { @Override public void run() { a.setFocusable(false); a.setEnabled(false); } }); } this.notifyObservers(); this.setChanged(); } } Adicionalmente, já percebi que a classe View poderia muito bem fazer este trabalho: Quando chegasse alguma notificação nova por parte da classe Controller, a classe View poderia desabilitar os seus componentes gráficos, caso fosse necessário. De qualquer forma, a minha duvida mantem-se: - Não é permitido à classe Controller fazer este trabalho? Muito obrigado a todos desde já. Cumprimentos, Edited February 9, 2013 at 05:08 PM by RubenFelix
RubenFelix Posted February 15, 2013 at 08:34 AM Author Report #495371 Posted February 15, 2013 at 08:34 AM Ninguem mais por dentro deste assunto? Obrigado.
HappyHippyHippo Posted February 15, 2013 at 10:25 AM Report #495376 Posted February 15, 2013 at 10:25 AM é que a classe de View chama um método da classe Controller não estás a ver o MVC um bocado ao contrário ? o View a chamar o Controller ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
RubenFelix Posted February 16, 2013 at 03:25 PM Author Report #495560 Posted February 16, 2013 at 03:25 PM O View apenas diz ao Controller que tem uma tentativa de autenticação. O controller valida a tentativa e diz então à view o que dizer ao utilizador da aplicação. Estou a errar no meu pensamento? Abraços,
eatg75 Posted February 28, 2013 at 12:55 PM Report #497369 Posted February 28, 2013 at 12:55 PM 1-para-1 está englobado no 1-para-N @HappyHippyHippo tens toda razao! Eu e que estava a fazer confuzao, normalmente os livros de Design Patterns apresentam exemplos de problemas onde sera necessario utilizar uma colecao, e dizem para sabermos de estamos diante de um problema onde e necessario o Observer Pattern para resolve-lo para ver nas pistas que falei na minha mensagem anterior. O problema que o author deste post colocou a priori parecia-me que era necessario o Observer Pattern para resolve-lo mas, mesmo assim parecia-me que nao era. Mas agora reconheco estava errado, basicamente e o mesmo que acontece com os eventos do Swing em Java e os eventos do Android. Obrigado man. Victarion seized the dusky woman by the wrist and pulled her to him. Victarion - She will do it. Go pray to your red god. Light your fire, and tell me what you see. Moqorro's dark eyes seemed to shine. Moqorro - I see dragons.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now