Controle de botões não funciona

20 respostas
Pedrosa

Boa tarde, estou tendo um probleminha na minha aplicação para controlar os botões, tenho meu form principal que aciona um outro, quando eu efetuo a transação nesse novo form, devo fecha-lo e mudar os botões do principal mas ele não esta fazendo correto.

//principal

private void btnTransferenciaActionPerformed(java.awt.event.ActionEvent evt) {
    Transferencia transferencia = new Transferencia(telefonia);
    transferencia.setVisible(true);
}

//form secundario

private void btnTransferirActionPerformed(java.awt.event.ActionEvent evt) {
    new Principal(getTelefonia()).retornaAtendimento();
    this.setVisible(false);
}

//retornaAtendimento no principal

public void retornaAtendimento(){
    TimerCall.stopTimer();
    trataBotoes();
}
   
public void trataBotoes(){
   btnDiscar.setEnabled(false);
   btnRediscar.setEnabled(true);
   btnDesligar.setEnabled(false);
   btnHold.setEnabled(false);
   btnUnhold.setEnabled(false);
   btnPausa.setEnabled(true);
   btnTransferencia.setEnabled(false);
   btnConferencia.setEnabled(false);
   btnDisponivel.setEnabled(true);
}

Ele chega nesse metodo trataBotoes, mas não habilita os meus botões , o que pode está acontecendo?

20 Respostas

davidbuzatto

O Swing não é Thread Safe!!!

Coloca os setEnabled dentro de um Runnable, e chama o método
SwingUtilities.invokeLater( new SeuRunnable );

Falow!

Pedrosa

Como faria isso nunca trabalhei com Runnable?

Pedrosa

Fiz assim mas não funcionou:

public void retornaAtendimento(){
	    System.out.println("retorna Atendimento classe principal");
	    TimerCall.stopTimer();
	    trataBotoes();
   }
   
   public static Runnable teste( ) {
	     
	     Runnable runnable = new Runnable() {
	 
	         public void run() {
	        	btnDiscar.setEnabled(false);
	     		btnRediscar.setEnabled(true);
	     		btnDesligar.setEnabled(false);
	     		btnHold.setEnabled(false);
	     		btnUnhold.setEnabled(false);
	     		btnPausa.setEnabled(true);
	     		btnTransferencia.setEnabled(false);
	     		btnConferencia.setEnabled(false);
	     		btnDisponivel.setEnabled(true);
	         }
	 
	     };
	 
	     Thread t = new Thread( runnable );
	     t.start();
		return t;
	 
	 }   
   
   public void trataBotoes(){
	   SwingUtilities.invokeLater( teste() ); 
   }
Pedrosa

Como fazer isso funcionar?

Guilherme_Silveira

Tenta tirar o t.start() dai…

Pedrosa

Não funcionou Guilherme, coloquei no modo debug estranho ele não entra no run(), eu preciso extender a Thread em minha classe?, pois está assim:

public class Principal extends javax.swing.JFrame {

Luca

Olá

Para TUDO, mas tudo mesmo e dá uma estudada em Threads e em Swing.

Qualquer outra coisa que eu disser só vai atrapalhar seu futuro.

[]s
Luca

davidbuzatto
public void trataBotoes( final JButton[] btns ) {
    
    final Runnable r = new Runnable() {
        
        public void run() {
            
            for ( int i = 0; i < btns.length; i++ ) {
                
                btns[ i ].setEnabled( !btns[ i ].isEnabled() );
                
            }
            
        }
        
    };
    
    Runnable executa = new Runnable() {
        
        public void run() {
            
            SwingUtilities.invokeLater( r );
            
        }
        
    };
    
    Thread t = new Thread( executa );
    t.start();
    
}
Funfo?
Pedrosa

Cara coloquei desse jeito, ele entra na thread nos 2 runs mais mas não troca o estado dos botões, não usei esse for com os botões eu preciso somente de alguns, o que esta de errado?

public void trataBotoes(  ) {
     
     final Runnable r = new Runnable() {
         
         public void run() {
            //chega aqui mas não faz nada 
            btnDiscar.setEnabled(false);
            btnRediscar.setEnabled(true);  	
            btnDesligar.setEnabled(false);
            btnHold.setEnabled(false);
            btnUnhold.setEnabled(false);
            btnPausa.setEnabled(true);
            btnTransferencia.setEnabled(false);
            btnConferencia.setEnabled(false);
            btnDisponivel.setEnabled(true);
             
         }
         
     };
     
     Runnable executa = new Runnable() {
         
         public void run() {
             
             SwingUtilities.invokeLater( r );
             
         }
         
     };
     
     Thread t = new Thread( executa );
     t.start();
     
 }
Pedrosa

Por favor alguém tem idéia do que está acontecendo?

U
public void trataBotoes(  ) {
     
     Runnable doRunnable = new Runnable() {
            public void run() {

            btnDiscar.setEnabled(false);
            btnRediscar.setEnabled(true);  	
            btnDesligar.setEnabled(false);
            btnHold.setEnabled(false);
            btnUnhold.setEnabled(false);
            btnPausa.setEnabled(true);
            btnTransferencia.setEnabled(false);
            btnConferencia.setEnabled(false);
            btnDisponivel.setEnabled(true);
            }
        };
        
        try {
            SwingUtilities.invokeAndWait(doRunnable);
        } catch (Exception ex) {
      }
}

Não precisa por em um Thread.

Boa Sorte

Pedrosa

Mesmo desse jeito não funciona.

Pedrosa

Nossa que saudade do javascript, mas como viram estou apanhando, alguem tem algum exemplo de como fazer o que eu quero, simplesmente habilitar e desabilitar alguns botões apos fechar um form secundario?

G

Primeiramente, gostaria de ressaltar que só deve ser usado o SwingUtilities.invokeLater se o metodo a ser chamado não estiver presente na (EDT - Event Dispatch Thread, que é a thread do Swing). Para saber se o metodo ja está presente ou nao é só fazer uma condicao chamando o método SwingUtilities.isEventDispatchThread(). Se retornar TRUE nao deve ser chamado o invokeLater. E se precisar chamar não deve ser incluída dentro de uma outra thread.

public void executaOperacao(){
   if (!SwingUtilities.isEventDispatchThread()){
          // NAO ESTÁ NA EDT, CHAMAR O INVOKE LATER
   }              
}

Pedrosa, o codigo que voce postou nao deixou clara a ordem na qual os eventos são chamados, pois pode ser que o metodo “trataBotoes” nao esteja sendo chamado no tempo certo.
Voce poderia postar o codigo de forma a mostrar a sequencia da execucao?

Gyowanny

Pedrosa

Valeu cara pela força a ordem esta assim:

/**
   * Objetivo: Retornar o atendimento apos uma transferencia 
   * Data: 07/08/2006
   */
   public void retornaAtendimento(){
	    System.out.println("<<<<<<<retorna Atendimento classe principal>>>>>>>");
	    TimerCall.stopTimer();
	    trataBotoes();
   }
   
   /**
   * Objetivo: Habilitar botoes apos uma transferencia 
   * Data: 07/08/2006
   */
   public void trataBotoes(  ) {
	     System.out.println("trata botoes");
	     final Runnable doRunnable = new Runnable() {
	    	 	 
	         public void run() {
	        	System.out.println("trata botoes 1 RUN");
	    	    btnDiscar.setEnabled(false);
	     		btnRediscar.setEnabled(false);
	     		btnDesligar.setEnabled(false);
	     		btnHold.setEnabled(false);
	     		btnUnhold.setEnabled(false);
	     		btnPausa.setEnabled(true);
	     		btnTransferencia.setEnabled(false);
	     		btnConferencia.setEnabled(false);
	     		btnDisponivel.setEnabled(true);
	     		System.out.println("passou em todos botoes");
	         }
	         
	 
	     };
	 Runnable executa = new Runnable() {
   		 public void run(){
   			 System.out.println("trata botoes 2 RUN");
    			SwingUtilities.invokeLater(doRunnable);
			
   		 }
   	 };	 
   	 Thread t = new Thread( executa );
	 t.start();
	
}
G

Tente tirar o SwingUtilities.invokeLater() de dentro da thread, ele ja eh uma thread, nao precisa estar dentro de outra. Se isso nao resolver, contact-me novamente

Pedrosa

como ficaria entao o codigo acima, fiz desse jeito:

Comentei a nova thread:

public void trataBotoes(  ) {
	     System.out.println("trata botoes");
	     
	     Runnable doRunnable = new Runnable() {
	    	 	 
	         public void run() {
	        	System.out.println("trata botoes 1 RUN");
	    	    btnDiscar.setEnabled(false);
	     		btnRediscar.setEnabled(false);
	     		btnDesligar.setEnabled(false);
	     		btnHold.setEnabled(false);
	     		btnUnhold.setEnabled(false);
	     		btnPausa.setEnabled(true);
	     		btnTransferencia.setEnabled(false);
	     		btnConferencia.setEnabled(false);
	     		btnDisponivel.setEnabled(true);
	     		
	     		System.out.println("passou em todos botoes");
	         }
	         
	 
	     };
	 /*Runnable executa = new Runnable() {
   		 public void run(){
   			 System.out.println("trata botoes 2 RUN");
    				SwingUtilities.invokeLater(doRunnable);
			
   		 }
   	 };	 
   	 Thread t = new Thread( executa );
	 t.start();
	*/
}

Onde colocaria a linha:
SwingUtilities.invokeLater(doRunnable);

sem essa linha nao executa o run()

G

deixe só essa linha descomentada: SwingUtilities.invokeLater(doRunnable);

Pedrosa

Que coisa estranha ele executa mas não faz nada:

public void trataBotoes() {
	     System.out.println("trata botoes");
	     
	     Runnable doRunnable = new Runnable() {
	    	 	 
	         public void run() {
	        	System.out.println("trata botoes 1 RUN");
	    	        btnDiscar.setEnabled(false);
	     		btnRediscar.setEnabled(false);
	     		btnDesligar.setEnabled(false);
	     		btnHold.setEnabled(false);
	     		btnUnhold.setEnabled(false);
	     		btnPausa.setEnabled(true);
	     		btnTransferencia.setEnabled(false);
	     		btnConferencia.setEnabled(false);
	     		btnDisponivel.setEnabled(true);
	     		
	     		System.out.println("passou em todos botoes");
	         }
	         
	 
	     };
	    	 SwingUtilities.invokeLater(doRunnable);
}
Pedrosa

Resolvi passando no construtor da classe secundaria a minha principal, não sendo necessário o trabalho com esse Runnable, porem estou com um novo problema.

Tenho 3 classes, Login, Principal e Telefonia.

No construtor do login:

Telefonia telefonia = null;
Principal principal = new Principal();
public Login() {
    telefonia = new Telefonia(principal);
    principal = new Principal(telefonia);
    telefonia.startTelefonia();
    initComponents();
    setLocationRelativeTo(null);
}

Construtor do principal

public Principal(final Telefonia telefonia) {

Na minha classe de telefonia ao ocorrer um evento preciso chamar um método que gerencia meus botoes.

public void gerenciaUI(String action){

Ele cai no método mas não faz essas mudanças, quando estou em telefonia:

if(isAutoAnswer()&& ((CallControlCall)eventList[i].getCall()).getCalledAddress().getName().equals(getGrupo())){
    setAtende(false);
}
if(isAtende()){
   //notificar que existe uma chamada
   setChamada(true);
}else{
   _principal.gerenciaUI("discar");//aqui conte os set.enables da vida
}

Construtor do telefonia

Principal _principal = null;
public Telefonia(Principal principal){
    setPrincipal(principal);
}
	
private void setPrincipal(Principal principal) {
    _principal = principal;
}

Não executa as mudanças nos botoes, porem cai no método, a zica que não consigo usar o debug do Eclipse, pois minha aplicação não acha um arquivo, estou me virando com mensagens para todo lado.

Criado 17 de agosto de 2006
Ultima resposta 31 de ago. de 2006
Respostas 20
Participantes 6