Я работаю над окном предложений с автоматическим раскрывающимся списком (например, Google), используя JWindow (а не JPopupMenu). Мой раскрывающийся список JWindow не является настраиваемым и не модальным (текстовое поле должно сохранять фокус во время ввода пользователем).Как получить уведомление при нажатии/нажатии строки заголовка окна
Я хотел бы закрыть раскрывающийся список, когда пользователь нажимает мышь в любом месте за пределами выпадающего меню или если приложение теряет фокус или свернуто или нажата клавиша эвакуации (в основном, как работает JPopupMenu).
У меня есть рабочий кроме того, что я не могу понять, как получить событие, когда пользователь нажимает кнопку заголовка основного кадра (что приводит к тому, что основной кадр выходит перед выпадающим списком).
Я боюсь, что нет ни одного события для этого, так как я ничего не получаю с этим слушателем:
Toolkit.getDefaultToolkit().addAWTEventListener(myTestListener, Integer.MAX_VALUE);
Как JPopupMenu добиться такого поведения, так или иначе?
EDIT: добавлен SSCCE:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class SSCCE
{
public static void main(String[] args) throws Exception
{
final JFrame frame = new JFrame();
JButton button = new JButton("open popup");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
openPopup(frame);
}
});
frame.setLayout(new FlowLayout());
frame.add(button);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void openPopup(JFrame frame)
{
final JWindow popupWindow = new JWindow();
popupWindow.setFocusable(false);
popupWindow.setSize(400, 400);
popupWindow.setLocation(frame.getX() + 200, frame.getY() + 200);
((JComponent) popupWindow.getContentPane()).setBorder(new MatteBorder(1, 1, 1, 1, Color.RED));
popupWindow.setVisible(true);
AWTEventListener awtEventListener = new AWTEventListener() {
@Override
public void eventDispatched(AWTEvent e)
{
System.out.println(e.toString());
if(e instanceof MouseEvent
&& ((MouseEvent) e).getID() == MouseEvent.MOUSE_PRESSED //
|| e instanceof FocusEvent
&& ((FocusEvent) e).getID() == FocusEvent.FOCUS_LOST //
|| e instanceof ComponentEvent
&& ((ComponentEvent) e).getID() == ComponentEvent.COMPONENT_MOVED
&& e.getSource() != popupWindow //
|| e instanceof ComponentEvent && ((ComponentEvent) e).getID() == ComponentEvent.COMPONENT_RESIZED
&& e.getSource() != popupWindow//
|| e instanceof WindowEvent && ((WindowEvent) e).getID() == WindowEvent.WINDOW_STATE_CHANGED //
|| e instanceof WindowEvent && ((WindowEvent) e).getID() == WindowEvent.WINDOW_ACTIVATED //
|| e instanceof WindowEvent && ((WindowEvent) e).getID() == WindowEvent.WINDOW_DEACTIVATED //
|| e instanceof WindowEvent && ((WindowEvent) e).getID() == WindowEvent.WINDOW_GAINED_FOCUS //
|| e instanceof WindowEvent && ((WindowEvent) e).getID() == WindowEvent.WINDOW_LOST_FOCUS //
|| e instanceof KeyEvent && ((KeyEvent) e).getKeyCode() == KeyEvent.VK_ESCAPE //
)
{
popupWindow.setVisible(false);
Toolkit.getDefaultToolkit().removeAWTEventListener(this);
}
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(awtEventListener, 0xFFFFFFFF);
}
}
Вы пробовали 'WindowListener.windowActivated()'? – whiskeyspider
Я считаю, что мой прослушиватель событий AWT должен также получить все события окна, включая windowActivated. Но я попробую еще раз ... (после тестирования: нет, я получаю windowActivated события, когда я сворачиваю и восстанавливаю основной фрейм, но не просто щелкнув по строке заголовка окна). – Zalumon
Насколько я помню, это невозможно или, по крайней мере, очень сложно. См. Например, http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6491619 – Radiodef