Сначала у меня была другая проблема, поэтому я сделал этот пост:
Слушатель мыши Java JPanel не работает над его компонентами
Ответы привели меня к появлению java GlassPane. Я видел другие посты на SO об этом, и все они указывают на эту статью:
http://weblogs.java.net/blog/alexfromsun/archive/2006/09/a_wellbehaved_g.html.
Я использовал пример из статьи (FinalGlassPane.java) и настроил его точно так же, как в тестовом приложении:
GlassPane glass = new GlassPane(this);
getRootPane().setGlassPane(glass);
GestureListener gl = new GestureListener();
glass.addMouseMotionListener(gl);
glass.addMouseListener(gl);
glass.setVisible(true);
if (glass instanceof AWTEventListener) {
AWTEventListener al = (AWTEventListener) glass;
Toolkit.getDefaultToolkit().addAWTEventListener(al,
AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
}
Но у меня все та же проблема, стекло не позволяет мне нажимать какие-либо кнопки (JButton) под ним.
Если вы любезно прочитали мой первоначальный вопрос SO и считаете, что GlassPane не для меня, опубликуйте альтернативное решение, в противном случае, скажите, почему это не работает.
Заранее спасибо.
РЕДАКТИРОВАТЬ: ЭТО РАБОТАЕТ, но перестает работать, когда я добавляю свой собственный MouseListener
Обратите внимание, что в своем коде я добавил свой собственный GestureListener
, я не могу добавить свой MouseListener к этой реализации - вот почему он не работает. Я снял эти строки, и стеклянная панель теперь работает правильно.
В коде (FinalGlassPane.java) есть это уведомление, касающееся MouseListener, которое я не совсем понимаю, поэтому мой новый вопрос заключается в том, как добавить собственный MouseListener в эту стеклянную панель?
/**
* If someone adds a mouseListener to the GlassPane or set a new cursor
* we expect that he knows what he is doing
* and return the super.contains(x, y)
* otherwise we return false to respect the cursors
* for the underneath components
*/
@Override
public boolean contains(int x, int y) {
if (getMouseListeners().length == 0 && getMouseMotionListeners().length == 0
&& getMouseWheelListeners().length == 0
&& getCursor() == Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)) {
return false;
}
return super.contains(x, y);
}
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:
Если я всегда возвращаю false в методе contains(int, int)
, кнопки всегда работают, а мой MouseListener на GlassPane - нет. Если я всегда возвращаю «super.contains (x, y)», происходит обратное: MouseListener на GlassPane работает, но я не могу щелкнуть какие-либо компоненты под ним.
ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ
Поэтому я пришел к выводу, что у меня нет (или нет) способа (с Java 6) разрешить моему Приложению иметь 2 слоя, которые могут одновременно получать события MouseListener (mousePressed, mouseReleased). В конце концов, я использовал решение моего первоначального вопроса, которое заключалось в создании собственного JButton и добавлении MouseListener к каждому экземпляру.