Jump to content

Java GUI - Update de UI através de outra classe


Recommended Posts

Posted (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 by RubenFelix
Posted

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.

Posted (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 by RubenFelix
Posted

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,

  • 2 weeks later...
Posted

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.

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.