我有一个JFrame,我在其中删除并添加组件,每次执行此操作时,我都会相应地调整框架大小。我添加了一个组件侦听器,但当然它由用户调整窗口大小和我的setSize()方法触发。
有没有办法从ComponentEvent中看到用户是调整窗口大小还是通过setSize()完成的?
我发现的可行解决方案是:
1.使用标志 - 布尔值调整大小 - 我在setSize()之前设置为true,之后设置为false。
2.添加mouseDragged侦听器并比较拖动前后的大小。
第二个绝对不是一个好选择。第一个可以工作,但我想知道我是否能够以简单的方式找到用户是否是调整窗口大小的人。
答案 0 :(得分:3)
我相应地调整了框架的大小
使用pack()有什么问题?
我删除并添加组件,每次执行此操作时,
然后,您应该在此处设置布尔值:
programResize == true:
panel.add(...);
frame.setSize(...); // this should cause the ComponentListener to fire
// the ComponentListener would then use programResize == false;
或者更好的选项可能是:
component.removeComponentListener(...);
panel.add(...);
frame.setSize(...);
component.addComponentListener(...);
我更喜欢这种方法,因为基于手动更新的所有逻辑都是自包含在一个地方,并且不需要定义布尔变量。
答案 1 :(得分:1)
有没有办法从ComponentEvent中看到用户是否 调整窗口大小或我通过setSize()?
是的,使用由Swing Timer重置的布尔标志
如果用户调整了窗口大小,那么ComponentListener会为每个像素触发一个新事件,一堆事件
通过确定contianer set(Xxx)大小是此事件仅被触发一次
有关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");
}
}