2010-08-10 38 views
0

L'application sur laquelle je travaille contient une JFrame principale, à partir de laquelle les utilisateurs pourraient éventuellement ouvrir une autre trame supplémentaire. J'essaie d'implémenter un tel comportement de l'application où la trame supplémentaire est minimisée (iconifiée) dès que la trame principale est minimisée. Je pensais à remplacer la méthode setExtendedState de l'image principale pour capturer le moment où elle est réduite, puis déclencher l'événement de changement de propriété à partir de là pour que la trame supplémentaire puisse agir sur elle.Minimisation d'une JFrame supplémentaire lorsque l'application principale JFrame est minimisée

J'ai cependant découvert que malheureusement, le setExtendedState surchargé n'est jamais appelé.

J'apprécierais grandement toute idée d'atteindre le comportement désiré. Voici le code utilisé pour les tests que je ...

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); 
    } 
} 

Répondre

1

il suffit d'ajouter WindowStateListener à MainFrame pour faire votre travail de code avec écouteur de modification de la propriété:

addWindowStateListener(new WindowStateListener() { 

     @Override 
     public void windowStateChanged(WindowEvent e) { 
       firePropertyChange(EXTENDED_STATE_KEY, e.getOldState(), e.getNewState()); 
     } 
    }); 
+0

Cela a fait l'affaire, merci! –

+0

En fait, il semble plus approprié d'ajouter WindowStateListener à la trame supplémentaire. Ensuite, il ne sera pas nécessaire d'ajouter une quelconque fonctionnalité au cadre principal pour obtenir le comportement souhaité. –

1

L'application Je travaille sur contient un JFrame principal, à partir de laquelle les utilisateurs pourraient éventuellement ouvrir un autre cadre supplémentaire

Les applications sont généralement conçues pour utiliser un seul JFrame. Les fenêtres supplémentaires sont créées en utilisant un JDialog. Lorsque vous créez la boîte de dialogue, assurez-vous de spécifier le cadre en tant que propriétaire de la boîte de dialogue. Maintenant, quand vous iconifiez/désiconifiez le cadre, la boîte de dialogue est automatiquement synchronisée.

+0

Merci. J'ai essayé cela, mais alors la fenêtre supplémentaire reste toujours au-dessus du cadre principal (même si je setAlwaysOnTop (faux);), n'est pas visible sur la barre des tâches et ne peut pas être minimisé/maximisé par lui-même. –