У меня есть JFrame (undecorated) с Glasspane. Эта рамка открывает JDialog (также undecorated и имеет также стеклянную панель) и прячется (setVisible (false)). Стеклянные стекла установлены с .setGlassPane(). Диалог открывается с помощью Рамы как владельца.JFrame Glasspane также над JDialog, но не должен
GlassPane расширяет JPanel и реализует AWTEventListener. Я использую его для изменения размеров фреймов и диалогов, поэтому он знает, что это родительский (Frame/Dialog) - это называется «цель».
В События внутри 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» я получаю IllegalComponentStateException, когда JFrame скрыта и я нажимаю на JDialog. В нем говорится, что «компонент должен показывать на экране, чтобы определить его местоположение». Это связано с тем, что GlassPane JFrame получает событие. Но Glasspane JDialog должен получить это. Я думаю, Glasspane JFrame находится перед JDialog. Но почему?
Спасибо за помощь!
Edit:
Вот пример:
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? – MadProgrammer
Я добавил рабочий пример с двумя кланами «Главная» и «Стеклянная панель». Извините, я мог бы проигнорировать «setUndecorated». Я не использую MouseListener, потому что это противоречит некоторым другим вещам. Честно говоря, я не совсем понимаю, почему. Но я помню, что у меня было больше проблем с MouseListeners, чем с GlassPane. – user1894572