Ir para o conteúdo
RubenFelix

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

Mensagens Recomendadas

RubenFelix

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.

Editado por RubenFelix

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
eatg75

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
RubenFelix

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,

Editado por RubenFelix

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

é 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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
RubenFelix

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,

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
eatg75

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.