Minimizar um jframe suplementar quando o aplicativo principal jframe é minimizado
Pergunta
O aplicativo em que estou trabalhando contém um JFrame principal, do qual os usuários podem eventualmente abrir outro quadro suplementar. Estou tentando implementar esse comportamento do aplicativo em que o quadro suplementar é minimizado (iconificado) assim que o quadro principal for minimizado.
Eu estava pensando em substituir o método SetExtendedState do quadro principal para capturar o momento em que ele é minimizado e, em seguida, disparar um evento de alteração da propriedade a partir daí, para que o quadro suplementar pudesse agir sobre ele.
Descobri, no entanto, que, infelizmente, o setetenpendstate substituído nunca é chamado.
Eu apreciaria muito qualquer idéias de alcançar o comportamento desejado. Abaixo está o código que usei para testar ...
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
public class IconifySupplementaryFrameTest {
public static void main(String[] args) {
(new MainFrame()).setVisible(true);
}
}
class MainFrame extends JFrame {
public static final String EXTENDED_STATE_KEY = "extendedState";
MainFrame() {
super("Iconify test - main window");
setLayout(new FlowLayout(FlowLayout.LEADING));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(400, 400);
setLocationByPlatform(true);
add(new JButton(new AbstractAction("Show supplementary frame") {
@Override
public void actionPerformed(ActionEvent e) {
SupplementaryFrame.doShow(MainFrame.this);
}
}));
}
@Override
public synchronized void setExtendedState(int state) {
// This overridden method is never called ???
int oldState = getExtendedState();
super.setExtendedState(state);
firePropertyChange(EXTENDED_STATE_KEY, oldState, state);
}
}
class SupplementaryFrame extends JFrame implements PropertyChangeListener {
private static SupplementaryFrame instance;
private SupplementaryFrame(final JFrame parentFrame) {
super("Iconify test - supplementary window");
setSize(300, 300);
setLocationRelativeTo(parentFrame);
parentFrame.addPropertyChangeListener(
MainFrame.EXTENDED_STATE_KEY, this);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
instance = null;
parentFrame.removePropertyChangeListener(
MainFrame.EXTENDED_STATE_KEY,
SupplementaryFrame.this);
SupplementaryFrame.this.dispose();
}
});
}
static void doShow(JFrame parentFrame) {
if(instance == null) {
instance = new SupplementaryFrame(parentFrame);
instance.setVisible(true);
}
else {
// omitted _ugly_ code to bring this window (instance) to front
}
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
int state = this.getExtendedState();
int parentState = ((Integer)evt.getNewValue()).intValue();
if((parentState & ICONIFIED) == ICONIFIED)
this.setExtendedState(state | ICONIFIED);
}
}
Solução
Basta adicionar windowstatelistener ao mainframe para fazer seu código funcionar com o ouvinte de alteração da propriedade:
addWindowStateListener(new WindowStateListener() {
@Override
public void windowStateChanged(WindowEvent e) {
firePropertyChange(EXTENDED_STATE_KEY, e.getOldState(), e.getNewState());
}
});
Outras dicas
O aplicativo em que estou trabalhando contém um JFrame principal, do qual os usuários podem eventualmente abrir outro quadro suplementar
Os aplicativos geralmente são projetados para usar um único JFrame. As janelas suplementares são criadas usando um JDialog. Ao criar a caixa de diálogo, especifique o quadro como o proprietário da caixa de diálogo. Agora, quando você iconifica/deiconifica o quadro, a caixa de diálogo é iconificada em sincronia automaticamente.