web-dev-qa-db-fra.com

Écouter les événements de redimensionnement de JFrame lorsque l'utilisateur fait glisser sa souris?

Lorsqu'un utilisateur clique sur le coin d'un JFrame pour redimensionner et fait glisser la souris, le JFrame se redessine en fonction de la position actuelle de la souris lorsque l'utilisateur se déplace. Comment pouvez-vous écouter ces événements?

Voici ce que j'ai essayé actuellement:

public final class TestFrame extends JFrame {
    public TestFrame() {
        this.addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // This is only called when the user releases the mouse button.
                System.out.println("componentResized");
            }
        });
    }

    // These methods do not appear to be called at all when a JFrame
    // is being resized.
    @Override
    public void setSize(int width, int height) {
        System.out.println("setSize");
    }

    @Override
    public void setBounds(Rectangle r) {
        System.out.println("setBounds A");
    }

    @Override
    public void setBounds(int x, int y, int width, int height) {
        System.out.println("setBounds B");
    }
}

Comment puis-je déterminer et restreindre la façon dont l'utilisateur redimensionne une fenêtre (en fonction du rapport hauteur/largeur actuel de la fenêtre) pendant qu'il se déplace autour de la souris?

30
Clinton

Vous devrez probablement remplacer quelque chose comme validate (n'oubliez pas d'appeler le super). Bien sûr, cela peut ne pas fonctionner si vous utilisez un système de fenêtrage configuré pour faire glisser les contours.

7

Vous pouvez ajouter un écouteur de composant et implémenter la fonction componentResized comme ça:

JFrame component = new JFrame("My Frame");

component.addComponentListener(new ComponentAdapter() 
{  
        public void componentResized(ComponentEvent evt) {
            Component c = (Component)evt.getSource();
            //........
        }
});

EDIT: Apparemment, pour JFrame, l'événement componentResized est lié à l'événement mouseReleased. C'est pourquoi la méthode est invoquée lorsque le bouton de la souris est relâché.

Une façon d'atteindre ce que vous voulez, est d'ajouter un JPanel qui couvrira toute la zone de votre JFrame. Ajoutez ensuite le componentListener au JPanel (componentResized pour JPanel est appelé même lorsque votre souris est toujours en train de glisser). Lorsque votre cadre est redimensionné, votre panneau sera également redimensionné.

Je sais, ce n'est pas la solution la plus élégante, mais ça marche!

40
Alex

Une autre solution de contournement (qui est très similaire à celle d'Alex mais un peu plus simple) consiste à écouter les événements à partir du volet racine de JFrame:

public final class TestFrame extends JFrame {
    public TestFrame() {
        this.getRootPane().addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                // This is only called when the user releases the mouse button.
                System.out.println("componentResized");
            }
        });
    }
}

Selon d'autres détails d'implémentation, il est possible que le volet racine soit modifié. Si c'est une possibilité, vous pouvez remplacer setRootPane() et gérer cela. Puisque setRootPane() est protégé et uniquement appelé depuis le constructeur, il est peu probable que vous ayez besoin de le faire.

6
vaughandroid