我有一个 JFrame,我在其中删除和添加组件,每次执行此操作时,我都会相应地调整框架的大小。我添加了一个组件侦听器,但它当然是由用户调整窗口大小和我的 setSize() 方法触发的。
有什么方法可以从 ComponentEvent 中查看用户是否调整了窗口大小还是我通过 setSize() 进行了调整?
我找到的可能解决方案是:
1. 使用一个标志 - 布尔调整大小 - 我在 setSize() 之前将其设置为 true,之后设置为 false。
2.添加mouseDragged监听器,比较拖动前后的大小。
第二个绝对不是一个好的选择。第一个可以工作,但我想知道我是否可以通过简单的方式找到用户是否是调整窗口大小的人。
问问题
8244 次
2 回答
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(...);
我更喜欢这种方法,因为基于手动更新的所有逻辑都包含在一个地方,并且不需要定义布尔变量。
于 2013-04-12T14:57:04.210 回答
1
有什么方法可以从 ComponentEvent 中查看用户是否调整了窗口大小还是我通过 setSize() 进行了调整?
是的,使用 Swing Timer 重置的布尔标志
在用户调整窗口大小的情况下,ComponentListener 每个像素触发一个新事件,一堆事件
通过确定 contianer set(Xxx)Size 这个事件是否只触发一次
关于来自 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");
}
}
于 2013-04-12T08:50:30.157 回答