1

I am trying to capture the moment a user finished resizing a JFrame through the mouse drag of a frame corner. I have so far found the below options, but they both print BLAH again and again until I am done stretching the window size. I only want it to print BLAH once I released the mouse after the continuous dragging of the JFrame corner resizing it. Any thoughts?

    frame.addComponentListener(new ComponentAdapter() 
    {  
            public void componentResized(ComponentEvent evt) {
                Component c = (Component)evt.getSource();
                System.out.println("BLAH");
            }
    });

AND

        frame.addComponentListener(new ComponentListener() {
        
        @Override
        public void componentShown(ComponentEvent e) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void componentResized(ComponentEvent e) {
            // TODO Auto-generated method stub
            System.out.println("BLAH");
            
        }
        
        @Override
        public void componentMoved(ComponentEvent e) {
            // TODO Auto-generated method stub
            
        }
        
        @Override
        public void componentHidden(ComponentEvent e) {
            // TODO Auto-generated method stub
            
        }
    }
    );
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Alon_T
  • 1,430
  • 4
  • 26
  • 47
  • Seems like you probably need to listen for mouse events with a MouseListener and then use the mouseReleased() method together with some smart logic to check whether the user is resizing or not – TrumpetFace Nov 01 '21 at 22:29
  • 1
    You won't capture the mouse events for the frame borders, as it's, generally, beyond your scope (handled at a much lower level). What I tend to do is use a single run Swing `Timer` set to a small amount of time (< 250 milliseconds) which gets restarted each time `componentResized` is called. So it will only trigger when `componentResized` stops been called, after a shortish delay – MadProgrammer Nov 01 '21 at 22:48
  • 1
    *I am trying to capture the moment a user finished resizing a jframe* - check out: https://stackoverflow.com/questions/20925193/using-componentadapter-to-determine-when-frame-resize-is-finished/20926024#20926024. The resized event will only be generated when the mouse is released. However, the frame will not be repainted while you are dragging so you see a black background. – camickr Nov 02 '21 at 00:35
  • *"I am trying to capture the moment a user **finished** resizing a `JFrame` through the mouse drag of a frame corner."* . . . ***Why?*** What application feature are you hoping to implement based on that knowledge? See also [What is the XY problem?](https://meta.stackexchange.com/q/66377/155831) – Andrew Thompson Nov 02 '21 at 02:39
  • 1
    @camickr - exactly what I needed. Works like charm. Thanks!!! – Alon_T Nov 02 '21 at 14:06

1 Answers1

1

The core problem is, you're unlikely to be able to detect when a mouse event occurs on the frame decorations, as it tends to be handled at a much lower level.

One trick I've used in the past, is to use a short lived, single run, Swing Timer, which is restarted each time componentResized is called. This means that the Timer will only trigger AFTER a "short delay" after componentResized stops been called, for example

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel label;
        private Timer resizeTimer;

        public TestPane() {
            setLayout(new GridBagLayout());
            label = new JLabel(".......");
            add(label);
            addComponentListener(new ComponentAdapter() {
                @Override
                public void componentResized(ComponentEvent e) {
                    if (resizeTimer == null) {
                        resizeTimer = new Timer(250, new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                label.setText(getSize().width + "x" + getSize().getHeight());
                                resizeTimer.stop();
                                resizeTimer = null;
                            }
                        });
                        resizeTimer.setRepeats(false);
                    }
                    resizeTimer.restart();
                }
            });
        }

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366