В java AWT или Swing, как я могу организовать ввод с клавиатуры, где мышь?
Работая над справочной системой, я бы хотел, чтобы каждый компонент предлагал некоторую помощь, когда наведена указатель мыши и "?" клавиша нажата. Вроде как всплывающие подсказки, кроме как с гораздо более обширной помощью - по сути, небольшой веб-браузер предназначен для отображения и отображения текста, изображений или более.
Я обнаружил, что независимо от того, где находится мышь, ввод всегда идет к одному и тому же KeyListener. Должен ли быть только один активный одновременно?
Для чего это стоит, это теперь работающая версия - спасибо за предложения!
/ ** * Основной класс JavaHelp хочет поддерживать функцию справки, чтобы, когда * пользователь вводит F1 над компонентом, он создает всплывающее окно, объясняющее * компонент. * Полная версия предназначена для того, чтобы быть "старшим братом" для всплывающих подсказок, используя * HTML-дисплей с интерактивными ссылками, встроенными изображениями и тому подобным. */ import javax.swing.*; импорт javax.swing.border.Border; импорт java.awt.*; импорт java.awt.event.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; класс Respond2Key extends AbstractAction { Component jrp; // Контрактный конструктор public Respond2Key( String text) { super( text); } // Конструктор, который гарантирует, что все сделано правильно public Respond2Key( String text, Component jrpIn) { super( text); System.out.println( "создание Respond2Key с компонентом" + jrpIn .toString ()); jrp = jrpIn; } public void setJrp( Component j) { jrp = j; } // Функциональность: каков отклик на открытый ключ действия void actionPerformed(ActionEvent e) { // использовать MouseInfo для получения позиции, преобразования в координаты панели, поиска компонента Point sloc = MouseInfo.getPointerInfo(). GetLocation(); SwingUtilities.convertPointFromScreen( sloc, (Component) jrp); Компонент c = jrp.getComponentAt( sloc); System.out.printf( "Мышь на%5.2f,%5.2f Компонент под мышью - это%s\n", sloc.getX(), sloc.getY(), c.toString()); } } //---------------------------------------------------------------- // Основной класс // ------------------------- --------------------------------------- открытый класс JavaHelp расширяет JFrame { // Конструктор объекта public JavaHelp() { // Начать конструкцию super( "Справочная система"); this.setSize( 640, 480); Содержимое контейнера = getContentPane(); contents.setLayout( new FlowLayout()); JButton b1 = приклад ( "button1", 64, 48); JButton b2 = приклад ( "button2", 96, 48); JButton b3 = приклад ( "button3", 128, 48); JPanel p1 = панель ("привет", 100, 100); JPanel p2 = панель ("мир", 200, 100); content.add( b1); content.add( p1); content.add( b2); content.add( p2); content.add( b3); JRootPane jrp = this.getRootPane(); jrp.getInputMap( jrp.WHEN_IN_FOCUSED_WINDOW) .put( KeyStroke.getKeyStroke( "F1"), "helpAction"); jrp.getActionMap().put( "helpAction", новый Respond2Key("frame",(Component)content)); this.setVisible( true); this.requestFocus(); this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); } // Внутренние классы для создания и прослушивания кнопок и панели. Класс ButtonListener реализует ActionListener { private String label = null; public void setLabel(String s) {label = s;} public void actionPerformed(ActionEvent e) { System.out.printf( "Работа с событием, помеченным как% s источник%s\n\n", метка, e.getSource().нанизывать()); } } // def butt( from, name, w, h) = новый Jbutton (...) защищенный JButton butt( String s, int w, int h) { JButton b = new JButton( s); b.setSize( w, h); ButtonListener oj = new ButtonListener(); oj.setLabel( s); b.addActionListener( oj); возврат (б); } // def pane = новая Jpanel(...) защищенная панель JPanel (имя строки, int w, int h) { JPanel p = новая JPanel(); p.setMinimumSize(новое измерение (ш, ч)); p.add (новый ярлык (имя)); p.setBackground( Color.black); p.setForeground( Color.red); возврат (р); } //-------------------------------- public static void main(String[] args) { JavaHelp jh = new JavaHelp(); } }
3 ответа
ввод всегда идет к одному и тому же KeyListener.
KeyEvent всегда отправляется компоненту с фокусом, расположение мыши не имеет ничего общего с тем, как генерируется событие ключа.
Вместо использования KeyListener, вы должны использовать Key Bindings
, Когда вы используете привязки клавиш, вы можете вызывать действие всякий раз, когда генерируется KeyStroke, добавляя привязку к корневой панели JFrame. Прочитайте раздел из учебника Swing по связыванию клавиш для получения дополнительной информации.
Теперь в действии, которое вы создаете, чтобы слушать "?" KeyStroke вы можете тогда:
- использовать
MouseInfo
класс, чтобы получить текущее местоположение мыши. - использовать
SwingUtilities.convertPointFromScreen(...)
чтобы конвертировать указатель мыши в корневую панель - тогда вы можете использовать
Conatiner.getComponentAt(...)
чтобы получить фактический компонент, мышь наведена - Как только вы знаете компонент, вы можете отобразить свою справочную информацию.
Я уверен, что есть лучший способ, но одно быстрое и грязное решение:
private final class HoverFocusListener extends MouseInputAdapter {
public void mouseEntered(MouseEvent e) {
e.getComponent().requestFocusInWindow();
}
}
Или, если необходимо:
public void mouseEntered(MouseEvent e) {
e.getSource().setFocusable(true);
for (Component c : refToParent.getComponents()) c.setFocusable(false);
e.getComponent().requestFocusInWindow();
}
Тогда просто .addMouseListener(new HoverFocusListener())
ко всем затронутым компонентам.
ввод последовательно поступает на аналогичный KeyListener.
KeyEvent постоянно отправляется в центральную часть, область мыши не зависит от того, как создается ключевое событие.
Вместо того, чтобы использовать KeyListener, вы должны использовать привязки клавиш. Когда вы используете привязки клавиш, вы можете вызвать действие в любой момент, когда создается KeyStroke, добавляя ограничение к корневому листу JFrame. Прочтите часть учебного упражнения Swing по привязкам клавиш для получения дополнительных данных.
В настоящее время в действии, которое вы совершаете, чтобы настроиться на «?» KeyStroke вы можете тогда, в этот момент:
используйте класс MouseInfo, чтобы получить текущую область мыши.
используйте SwingUtilities.convertPointFromScreen(...) для переключения подсветки мыши по сравнению с корневым листом
затем, в этот момент, вы можете использовать Container.getComponentAt(...) для получения подлинного сегмента мыши.
когда вы знаете часть, вы можете показать свои вспомогательные данные.