Alon_T
Alon_T

Reputation: 1440

Capture JFrame resize only once, when mouse is released

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

Upvotes: 1

Views: 259

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347334

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

    }
}

Upvotes: 1

Related Questions