JDialog bloqueando outras aplicações

2 respostas
swingjava
F

Pessoal,

Tenho uma thread que exibe um dialogo de progressão durante um processamento. Este dialogo abre e fecha várias e várias vezes. O problema é que todas as vezes que ele abre, ele aparece na frente de toda e qualquer aplicação que o usuário esteja mexendo.
Exemplo: usuário coloca determinado processamento no sistema, e abre o navegador ou o word. A medida que o dialogo de progressão aparece, ele aparece na frente de todos estes aplicativos. O que impossibilita que o usuário continue fazendo o que estava fazendo, e aí inutiliza o computador durante o processamento.

Segue o código do dialogo:

/**

  • Classe que implementa o pattern Observer. Essa classe é destinada a notificar um {link DialogoProgressao} se ele
  • deve ser exibido na tela ou não.

*/
class ObserverDialogo extends Observable {

/**

  • Método que notifica um Observer que o estado do objeto foi alterado.
    */
    public void notifica(boolean isExibe) {
    setChanged();
    if (isExibe) {
    notifyObservers(“exibeDialogo”);
    } else {
    notifyObservers(“fechaDialogo”);
    }
    }
    }

public class DialogoProgressao extends JDialog implements KeyListener, Observer, Runnable {

private static final long serialVersionUID = 1L;

private JLabelComp msgLinha51;

private JLabelComp msgLinha52;

private JProgressBar progressao;

/**
  • Observer para notificar a alteração de estado no {link DialogoProgressao} para que ele seja exibido.
    /
    private ObserverDialogo observer;
    /
    *
  • Objeto que armazena a mensagem a ser exibida no Diálogo.
    /
    private String mensagem;
    private JPanelComp painelLabels;
    private ThreadExibicao threadExibicao;
    /
    *
  • Variável criada para verificar em outros pontos do sistema se o diálogo progressão foi notificado para ser exibido
  • ou fechado.
    */
    private boolean isNotificado;
public DialogoProgressao(Window sistema) throws NumberFormatException, Exception {

super(sistema, ConstantesString.NOME_SISTEMA.toString());

setModal(true);

setFocusableWindowState(false);

/*

* Cria um novo observer para verificar a existência de mensagens a serem exibidas e adiciona o próprio diálogo como

* observador.

*/

if (sistema != null) {

observer = new ObserverDialogo();

observer.addObserver(this);

}

setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);

setLayout(new BorderLayout());

if (Platform.isWindows()) {

setUndecorated(true);

}

msgLinha51 = new JLabelComp();

msgLinha52 = new JLabelComp();

LookAndFeel lookAndFeelAnterior = UIManager.getLookAndFeel();

UIManager.setLookAndFeel(new MetalLookAndFeel());

// copy progress bar defaults

HashMap<Object, Object> progressDefaults = new HashMap<>();

for (Map.Entry<Object, Object> entry : UIManager.getDefaults().entrySet()) {

if (entry.getKey().getClass() == String.class && ((String) entry.getKey()).startsWith(ProgressBar)) {

progressDefaults.put(entry.getKey(), entry.getValue());

}

}

// set nimbus

UIManager.setLookAndFeel(lookAndFeelAnterior);

// copy back progress bar defaults

for (Map.Entry<Object, Object> entry : progressDefaults.entrySet()) {

UIManager.getDefaults().put(entry.getKey(), entry.getValue());

}

progressao = new JProgressBar();

progressao.setIndeterminate(true);

painelLabels = new JPanelComp(new BorderLayout());

painelLabels.add(msgLinha51, BorderLayout.NORTH);

painelLabels.add(msgLinha52, BorderLayout.SOUTH);

add(painelLabels, BorderLayout.NORTH);

add(progressao, BorderLayout.SOUTH);

setSize(500, 75);

addKeyListener(this);

setLocationRelativeTo(sistema);

setResizable(false);

}

/**

  • Método que monta a janela de diálogo com progressão com o layout específico
  • param sistema
  • - Janela que será utilizada para ser a referência de centralização do diálogo.
    
  • throws Exception
    */
    public void montaDialogoProgressao(JFrame sistema) throws Exception {
    // Verifica se o sistema é diferente de Linux para setar a borda dentro do dialogo progressão. No Linux a borda
    // “corta” parte do texto dentro do lialogo. André Nogueira 26/03/2014
    LayoutComp layoutAtivo = LayoutCompManager.getLayoutAtivo();
    if (layoutAtivo != null) {
    if (Platform.isWindows()) {
    getRootPane().setBorder(BorderFactory.createLineBorder(layoutAtivo.getCorBordaTelas(), 4));
    }
    msgLinha51.setForeground(layoutAtivo.getForeground1());
    msgLinha52.setForeground(layoutAtivo.getForeground1());
    Color corFundoPainel = layoutAtivo.getBackgroundPainel();
    painelLabels.setBackground(corFundoPainel);
    progressao.setBackground(corFundoPainel);
    getContentPane().setBackground(corFundoPainel);
}
setSize(500, 75 + ((isUndecorated() || sistema == null) ? 0 : sistema.getInsets().top));
setLocationRelativeTo(sistema);

}

public JLabelComp getMsgLinha52() {

return msgLinha52;

}
public void setMsgLinha52(JLabelComp msg) {

this.msgLinha52 = msg;

}
public JLabelComp getMsgLinha51() {

return msgLinha51;

}
public void setMsgLinha51(JLabelComp msgLinha51) {

this.msgLinha51 = msgLinha51;

}
Override

public void keyTyped(KeyEvent e) {

}
Override

public void keyPressed(KeyEvent e) {

if ((e.getKeyCode() == C) && (e.getModifiers() == 2)) {

try {

Comunicacao.getInstance().writeBlocoAlfaNumerico(3);

} catch (Exception e1) {

Log.getInstance().gravaErro(getClass(), e1);

}

}

}
Override

public void keyReleased(KeyEvent e) {

}
public JProgressBar getProgressao() {

return progressao;

}
public void setProgressao(JProgressBar progressao) {

this.progressao = progressao;

}
Override

public void update(Observable o, Object arg) {

/*

* Ao receber uma mensagem do Observador para exibir o dialogo com progressão é verificado se o próprio já não está

* visível para evitar que se crie várias threads para exibir o DialogoProgressao.

*/

if (exibeDialogo.equals(arg) && (!isVisible() || !isDisplayable())) {

if (threadExibicao == null) {

threadExibicao = new ThreadExibicao(this);

}

if (threadExibicao.isInterrupted() || !threadExibicao.isAlive()) {

try {

threadExibicao.start();

} catch (IllegalThreadStateException e) {

threadExibicao = new ThreadExibicao(this);

threadExibicao.start();

}

}
} else if (isVisible() || isDisplayable()) {
  requestFocus();
}
/*
 * Caso receba uma mensagem para fechar o diálogo, simplesmente o fecha e interrompe a execução da thread.
 */
if ("fechaDialogo".equals(arg)) {
  SwingUtilities.invokeLater(new Runnable() {
Override
    public void run() {
      if (isVisible() || isDisplayable()) {
        dispose();
      }
    }
  });
  if (threadExibicao != null) {
    threadExibicao.interrupt();
    /*
     * Aguarda a thread morrer antes de anula-la. Isso é necessário para evitar que entre uma mensagem e outra algo
     * seja perdido pelo fato do objeto não ter se anulado ainda.
     */
    try {
      threadExibicao.join();
    } catch (Exception e) {
      Log.getInstance().gravaErro(getClass(), e);
    }
  }
  threadExibicao = null;
}

}

public String getMensagem() {

return mensagem;

}

/**

  • Método que seta a mensagem a ser exibida no {link DialogoProgressao}. Nesse método é notificada a alteração de
  • estado do observer para que o {link DialogoProgressao} seja exibido ou fechado, caso o parâmetro informado seja
  • null.
  • param mensagem
  • - Mensagem a ser exibida. Caso seja informado <code>null</code> e o {link DialogoProgressao} esteja
    
  • visível, ele será fechado.
    
*/

public void setMensagem(String mensagem) {

if (mensagem != null) {

this.mensagem = mensagem;

getMsgLinha51().setHorizontalAlignment(JLabelComp.CENTER);

getMsgLinha51().setText(mensagem);

if (observer != null) {

observer.notifica(true);

}

} else {

getMsgLinha51().setHorizontalAlignment(JLabelComp.LEFT);

if (observer != null) {

observer.notifica(false);

}

}

}
public void setMensagem(boolean vf, String mensagem) {

if (vf) {

setMensagem(mensagem);

}

}
Override

public void run() {

/*

* Uma thread dessa classe deve apenas exibir o DialogoProgressao. É feito em uma thread separada para não travar o

* processamento do sistema.

*/

SwingUtilities.invokeLater(new Runnable() {
Override
  public void run() {
    if (!isVisible()) {
      setVisible(true);
    }
  }
});

}

public ObserverDialogo getObserver() {

return observer;

}
public void setObserver(ObserverDialogo observer) {

this.observer = observer;

}
public void notifica(boolean isExibe) {

isNotificado = isExibe;

if (observer != null) {

observer.notifica(isExibe);

} else {

if (isExibe) {

SwingUtilities.invokeLater(new Runnable() {
Override
      public void run() {
        if (!isVisible()) {
          setVisible(true);
        }
      }
    });
  } else {
    SwingUtilities.invokeLater(new Runnable() {
Override
      public void run() {
        dispose();
      }
    });
  }
}

}

public boolean isNotificado() {

return isNotificado;

}
public void setNotificado(boolean isNotificado) {

this.isNotificado = isNotificado;

}

}

class ThreadExibicao extends Thread {

private DialogoProgressao dialogo;

public ThreadExibicao(DialogoProgressao dialogo) {

super(ExibicaoDialogoProgressao);

this.dialogo = dialogo;

}
Override

public void run() {

if (!dialogo.isVisible()) {

dialogo.setVisible(true);

}

}

}

A chamada na Thread é feita através dos métodos montaDialogoProgressao e notifica(true) em sequência.

Será que alguém tem ideia do que possa ser?

2 Respostas

Rodrigo_Void

Olá,
a propriedade que faz isso é alwaysOnTop=true

Andrauss

Olá, verifique se seu dialog está associado ao Frame pai (frame principal da aplicação), isso é passado através do construtor da JDialog, caso esse valor seja null a dialog terá esse comportamento (se sobrepor às outras janelas), caso esteja “associado” ao frame principal o que ocorrerá (no windows) é que o ícone do sistema irá piscar.

(na verdade o problema se resolve chamando setAutoRequestFocus(false); no construtor da dialog, testei apenas no windows)

Criado 18 de abril de 2017
Ultima resposta 19 de abr. de 2017
Respostas 2
Participantes 3