2014-06-07 29 views
6

Pracując nad systemem pomocy, chciałbym, aby każdy komponent oferował pomoc, gdy mysz jest nad nim i "?" klawisz jest wciśnięty. Coś w rodzaju podpowiedzi, z wyjątkiem znacznie obszerniejszej pomocy - w istocie mała przeglądarka ma wyświetlać tekst, obrazy lub więcej.w java awt lub swing, w jaki sposób mogę ustawić wejście klawiatury tak, aby poruszało się tam, gdzie jest mysz?

To, co znajduję, to fakt, że niezależnie od tego, gdzie jest mysz, dane wejściowe zawsze trafiają do tego samego KeyListener. Czy jest tylko jeden aktywny na raz?

Co jest warte, to jest teraz działająca wersja - dzięki za sugestie!

 
    /** 
    * Main class JavaHelp wants to support a help function so that when 
    * the user types F1 above a component, it creates a popup explaining 
    * the component. 
    * The full version is intended to be a big brother to tooltips, invoking 
    * an HTML display with clickable links, embedded images, and the like. 
    */ 


    import javax.swing.*; 
    import javax.swing.border.Border; 
    import java.awt.*; 
    import java.awt.event.*; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.event.KeyEvent; 
    import java.awt.event.KeyListener; 

    class Respond2Key extends AbstractAction 
    { 
    Component jrp; 

    // Contract consructor 
    public Respond2Key(String text) 
    { 
     super(text); 
    } 

    // Constructor that makes sure it gets done right 
    public Respond2Key(String text, Component jrpIn) 
    { 
     super(text); 
     System.out.println("creating Respond2Key with component " + jrpIn 
             .toString 
             ()); 
     jrp = jrpIn; 
    } 

    public void setJrp(Component j) { 
     jrp = j; 
    } 


    // Functionality: what is the response to a key 
    public void actionPerformed(ActionEvent e) 
    { 
     // use MouseInfo to get position, convert to pane coords, lookup component 
     Point sloc = MouseInfo.getPointerInfo().getLocation(); 

     SwingUtilities.convertPointFromScreen(sloc, (Component) jrp); 

     Component c = jrp.getComponentAt(sloc); 
     System.out.printf("Mouse at %5.2f,%5.2f Component under mouse is %s\n", 
       sloc.getX(), sloc.getY(), c.toString()); 
    } 
    } 


    //---------------------------------------------------------------- 
    // The main class 
    //---------------------------------------------------------------- 
    public class JavaHelp extends JFrame 
    { 
    // The object constructor 
    public JavaHelp() 
    { 
     // Start construction 
     super("Help System"); 
     this.setSize(640, 480); 
     Container contents = getContentPane(); 
     contents.setLayout(new FlowLayout()); 


     JButton b1 = butt( "button1", 64, 48); 
     JButton b2 = butt( "button2", 96, 48); 
     JButton b3 = butt( "button3", 128, 48); 
     JPanel p1 = pane("hello", 100, 100); 
     JPanel p2 = pane("world", 200, 100); 

     contents.add(b1); 
     contents.add(p1); 
     contents.add(b2); 
     contents.add(p2); 
     contents.add(b3); 

     JRootPane jrp = this.getRootPane(); 
     jrp.getInputMap(jrp.WHEN_IN_FOCUSED_WINDOW) 
     .put(KeyStroke.getKeyStroke("F1"), "helpAction"); 
     jrp.getActionMap().put("helpAction", 
        new Respond2Key("frame",(Component)contents) 
        ); 
     this.setVisible(true); 
     this.requestFocus(); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    } 

    // Inner classes for instantiating and listening to button, and panel. 
    class ButtonListener implements ActionListener 
    { 
     private String label = null; 

     public void setLabel(String s) {label = s;} 

     public void actionPerformed(ActionEvent e) 
     { 
     System.out.printf("Dealing with event labeled %s source %s\n\n", 
        label, 
        e.getSource().toString()); 
     } 

    } 

    // def butt(from, name, w, h) = new Jbutton (...) 
    protected 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); 
     return (b); 
    } 

    // def pane = new Jpanel(...) 
    protected JPanel pane(String name, int w, int h) 
    { 
     JPanel p = new JPanel(); 
     p.setMinimumSize(new Dimension(w, h)); 
     p.add(new Label(name)); 
     p.setBackground(Color.black); 
     p.setForeground(Color.red); 
     return (p); 
    } 

    //-------------------------------- 
    public static void main(String[] args) 
    { 
     JavaHelp jh = new JavaHelp(); 
    } 



    } 





Odpowiedz

3

Wejście zawsze trafia do tego samego KeyListener.

KeyEvent jest zawsze wywoływane w komponencie z fokusem, lokalizacja myszy nie ma nic wspólnego z generowaniem zdarzenia klucza.

Zamiast używać KeyListener, powinieneś używać Key Bindings. Podczas korzystania z powiązań kluczy można wywołać działanie po wygenerowaniu klucza KeyStroke przez dodanie powiązania z panelem głównym JFrame. Przeczytaj sekcję z samouczka Swinga na temat Key Bindings, aby uzyskać więcej informacji.

Teraz w Akcji, którą tworzysz, aby słuchać "?" KeyStroke można wtedy:

  1. użyć klasy MouseInfo, aby uzyskać aktualną lokalizację myszy.
  2. użyć SwingUtilities.convertPointFromScreen(...) przekonwertować punkt myszy, aby być w stosunku do okienka głównego
  3. następnie można użyć Conatiner.getComponentAt(...) aby uzyskać rzeczywisty składnik mysz jest nad
  4. gdy wiesz komponentu można wyświetlić informacje pomocy .
+0

Perfect - działa jak urok. – ConorR

+0

Jesteście najlepsi - dzięki wam obojgu! – ConorR

3

Jestem pewien, że istnieje lepszy sposób, ale jeden szybki i brudny rozwiązanie:

private final class HoverFocusListener extends MouseInputAdapter { 
    public void mouseEntered(MouseEvent e) { 
    e.getComponent().requestFocusInWindow(); 
    } 
} 

Albo, jeśli to konieczne:

public void mouseEntered(MouseEvent e) { 
    e.getSource().setFocusable(true); 
    for (Component c : refToParent.getComponents()) c.setFocusable(false); 
    e.getComponent().requestFocusInWindow(); 
} 

Wtedy właśnie .addMouseListener(new HoverFocusListener()) wszystkich elementach, których dotyczy.

+0

Czy ta zmiana będzie się koncentrować za każdym razem, gdy się najeżdżam? – ConorR