JDialog bloqueando outras aplicações

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?

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

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)