Listen to JFrame resize events as the user drags their mouse?

81,422

Solution 1

You probably need to override something like validate (don't forget to call the super). Of course, that still may not work if you are using a windowing system to configured to drag outlines.

Solution 2

You can add a component listener and implement the componentResized function like that:

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

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

EDIT: Apparently, for JFrame, the componentResized event is hooked to the mouseReleased event. That's why the method is invoked when the mouse button is released.

One way to achieve what you want, is to add a JPanel that will cover the whole area of your JFrame. Then add the componentListener to the JPanel (componentResized for JPanel is called even while your mouse is still dragging). When your frame is resized, your panel will also be resized too.

I know, this isn't the most elegant solution, but it works!

Solution 3

Another workaround (which is very similar to Alex's but a little more straightforward) is to listen to the events from the JFrame's root pane instead:

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

Depending on other implementation details, it's possible that the root pane might be changed. If that's a possibility then you could override setRootPane() and deal with that. Since setRootPane() is protected and only called from the constructor though, it's unlikely you'll need to do that.

Share:
81,422
Clinton
Author by

Clinton

Builds things

Updated on September 12, 2020

Comments

  • Clinton
    Clinton over 3 years

    When a user clicks on the corner of a JFrame to resize and drags the mouse around, the JFrame redraws based on the current position of the mouse as the user drags. How can you listen to these events?

    Below is the what I have currently tried:

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

    How can I determine and constrain how the user resizes a window (based on the current aspect ratio of the window) as they are dragging around the mouse around?

  • Clinton
    Clinton over 14 years
    Thanks for the prompt response. However, componentResized only appears to be called when the user releases the mouse button. Is it possible to listen to resize events as the user is dragging the mouse?
  • Alex Ntousias
    Alex Ntousias over 14 years
    @Clinton True! Sorry about that, I didn't read your question thoroughly!
  • Alex Ntousias
    Alex Ntousias over 14 years
    @Clinton I was curious of how can this be done, and the only way I found was to add a JPanel in the JFrame. I don't know if this helps you. I've updated my answer.
  • Clinton
    Clinton over 14 years
    Thanks for your revised solution. I gave it a try and it worked well. However, in my case the validate option came out a little cleaner.
  • Tim van Dalen
    Tim van Dalen almost 13 years
    How would I call the super for this? I thought you could only call super in a constructor?
  • Saurabh
    Saurabh over 12 years
    -1. This is basically a duplicate of the code in the question (which we already know does not solve the problem.)
  • Anonymous Penguin
    Anonymous Penguin over 10 years
    Shouldn't it be public void TestFrame() {...?
  • Drew Noakes
    Drew Noakes almost 10 years
    @AnnonomusPenguin, no, that's a constructor declaration, and constructors don't specify return types such as void.
  • burglarhobbit
    burglarhobbit over 8 years
    +1 cause I wouldn't have to override the function in a seperate class! :) This answer is helping even after 5 years.
  • TomeeNS
    TomeeNS almost 8 years
    ERROR: the second line should go: component.addComponentListener(new ComponentListener() { @Override public void componentResized(ComponentEvent e) { // TODO some action }}
  • MAXdB
    MAXdB almost 5 years
    "// This is only called when the user releases the mouse button." -- it appears that it isn't merely when the mouse button is released. When I use this code, it is called incessantly, which would support a dynamic resize; any way to resize once upon release of the mouse?
  • H.Sheng
    H.Sheng about 3 years
    copy @MAXdB: any way to resize once upon release of the mouse?