【发布时间】:2013-05-19 22:05:34
【问题描述】:
我有一个带有 Glasspane 的 JFrame(未装饰)。 此框架打开一个 JDialog(也未装饰,也有一个 glassPane)并隐藏自身(setVisible(false))。 Glasspanes 使用 .setGlassPane() 设置。 对话框以 Frame 作为所有者打开。
GlassPane 扩展了 JPanel 并实现了 AWTEventListener。 我用它来调整框架和对话框的大小,所以它知道它是父级(框架/对话框)——这被称为“目标”。
GlassPane 中的事件是这样处理的:
public void eventDispatched(AWTEvent event) {
if (target instanceof JFrame) {
e = SwingUtilities.convertMouseEvent(
((MouseEvent) event).getComponent(),
(MouseEvent) event, ((JFrame) target).getGlassPane());
} else if (target instanceof JDialog) {
e = SwingUtilities.convertMouseEvent(
((MouseEvent) event).getComponent(),
(MouseEvent) event, this);
}
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
this.startPos = target.getLocationOnScreen();
}
}
在“target.getLocationOnScree”处,当 JFrame 被隐藏并单击 JDialog 时,我得到一个 IllegalComponentStateException。它说“组件必须显示在屏幕上才能确定其位置”。这是因为 JFrame 的 GlassPane 获取了事件。但是 JDialog 的 Glasspane 应该得到它。我认为,JFrame 的 Glasspane 在 JDialog 前面。但为什么呢?
感谢您的帮助!
编辑:
这是一个例子:
import java.awt.AWTEvent;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import javax.swing.JDialog;
import javax.swing.JFrame;
public class Main {
static JFrame frame;
static JDialog dialog;
public static void main(String[] args) {
frame = new JFrame();
frame.setSize(600,600);
GlassPane frameGlas = new GlassPane(frame);
frame.setGlassPane(frameGlas);
frame.setVisible(true);
frameGlas.setVisible(true);
dialog = new JDialog(frame);
dialog.setSize(100, 100);
GlassPane dialogGlas = new GlassPane(dialog);
dialog.setGlassPane(dialogGlas);
AWTEventListener al = (AWTEventListener) frameGlas;
Toolkit.getDefaultToolkit().addAWTEventListener(
al,
AWTEvent.MOUSE_MOTION_EVENT_MASK
| AWTEvent.MOUSE_EVENT_MASK);
dialogGlas.setVisible(true);
dialog.setVisible(true);
}
}
import java.awt.AWTEvent;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class GlassPane extends JPanel implements AWTEventListener {
/**
*
*/
private static final long serialVersionUID = 5110857185182004819L;
private final Window target;
public GlassPane(Window target) {
super(null);
this.target = target;
}
public void eventDispatched(AWTEvent event) {
if (event instanceof MouseEvent) {
MouseEvent originalEvent = (MouseEvent) event;
MouseEvent e = originalEvent;
if (target instanceof JDialog) {
e = SwingUtilities.convertMouseEvent(
((MouseEvent) event).getComponent(),
(MouseEvent) event, this);
}
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
Point p = target.getLocationOnScreen();
System.out.println(p.getX());
}
}
}
}
【问题讨论】:
-
听起来更像是您的鼠标侦听器使用框架作为目标而不是对话框,但除非您提供问题的工作示例,否则将无法提供帮助。想到的另一个问题是,你为什么不直接使用 MouseListener?
-
我添加了一个包含“Main”和“GlassPane”两个类的工作示例。抱歉,我本可以忽略“setUndecorated”。我不使用 MouseListener 因为这与其他一些东西冲突。老实说,我不太记得为什么。但我记得我在 MouseListeners 上遇到的麻烦比在 GlassPane 上要麻烦得多
标签: java jframe mouseevent jdialog glasspane