Java ComponentResized - Detect whether user resized the window or it was resized programatically

StackOverflow https://stackoverflow.com/questions/15966223

質問

I have a JFrame in which I remove and add components and each time I do this, I resize the frame accordingly. I added a Component Listener but of course it gets triggered both by the user resizing the window and also by my setSize() methods.
Is there any way to see from the ComponentEvent whether the user resized the window or I did through setSize()?
The posible solutions I found are:
1. Use a flag - boolean resizing - which I set to true before setSize() and to false after that.
2. Add a mouseDragged listener and compare sizes before and after the drag.
The second one is definitely not a good choice. The first one would work but I would like to know if I can find in a simple way whether the user is the one who resized the window or not.

役に立ちましたか?

解決

I resize the frame accordingly

Whats wrong with using pack()?

I remove and add components and each time I do this,

Then this is where you should set your Boolean value:

programResize == true:
panel.add(...);
frame.setSize(...); // this should cause the ComponentListener to fire
// the ComponentListener would then use programResize == false;

Or a better option option could be:

component.removeComponentListener(...);
panel.add(...);
frame.setSize(...);
component.addComponentListener(...);

I like this approach better because all the logic based on the manual update is self contained in one place and there is no need to define a Boolean variable.

他のヒント

Is there any way to see from the ComponentEvent whether the user resized the window or I did through setSize()?

yes it is, use boolean flag reseted by Swing Timer

  • in the case that user resized window then ComponentListener firing a new event per every pixel, bunch of events

  • by determine the contianer set(Xxx)Size is this event fired only once time

example about events from ComponentListner

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

public class ComponentEventDemo extends JPanel
        implements ComponentListener, HierarchyListener,
        ItemListener {

    private JFrame frame;
    private static final long serialVersionUID = 1L;
    private JTextArea display;
    private JLabel label;
    private JButton button = new JButton("Change Size");
    private String newline = "\n";

    public ComponentEventDemo() {
        display = new JTextArea();
        display.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(display);
        scrollPane.setPreferredSize(new Dimension(350, 200));
        label = new JLabel("This is a label", JLabel.CENTER);
        label.addComponentListener(this);
        JCheckBox checkbox = new JCheckBox("Label visible", true);
        checkbox.addItemListener(this);
        checkbox.addComponentListener(this);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Dimension dim = frame.getPreferredSize();
                if (!dim.equals(new Dimension(800, 600))) {
                    frame.setPreferredSize(new Dimension(800, 600));
                    frame.pack();
                } else {
                    frame.setPreferredSize(new Dimension(400, 300));
                    frame.pack();
                }
            }
        });
        JPanel panel = new JPanel(new GridLayout(1, 3));
        panel.add(label);
        panel.add(checkbox);
        panel.add(button);
        panel.addComponentListener(this);
        frame = new JFrame("ComponentEventDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.add(panel, BorderLayout.PAGE_END);
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            label.setVisible(true);
            label.revalidate();
            label.repaint();
        } else {
            label.setVisible(false);
        }
    }

    protected void displayMessage(String message) {
        //If the text area is not yet realized, and
        //we tell it to draw text, it could cause
        //a text/AWT tree deadlock. Our solution is
        //to ensure that the text area is realized
        //before attempting to draw text.
        // if (display.isShowing()) {
        display.append(message + newline);
        display.setCaretPosition(display.getDocument().getLength());
        //}
    }

    @Override
    public void componentHidden(ComponentEvent e) {
        //displayMessage(e.getComponent().getClass().getName() + " --- Hidden");
    }

    @Override
    public void componentMoved(ComponentEvent e) {
        //displayMessage(e.getComponent().getClass().getName() + " --- Moved");
    }

    @Override
    public void componentResized(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Resized ");
    }

    @Override
    public void componentShown(ComponentEvent e) {
        //displayMessage(e.getComponent().getClass().getName() + " --- Shown");
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ComponentEventDemo componentEventDemo = new ComponentEventDemo();
            }
        });
    }

    @Override
    public void hierarchyChanged(HierarchyEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Hierarchy changed");
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top