在帮助系统上工作,我希望每个组件在鼠标悬停时提供一些帮助并且“?”按下键 . 有点像工具提示,除了更广泛的帮助 - 基本上一个小的Web浏览器旨在弹出和显示文本,图像或更多 .
我发现无论鼠标在哪里,输入总是转到同一个KeyListener . 是否应该一次只有一个活跃?
对于它的 Value ,这是现在正在运行的版本 - 感谢您的建议!
/**
* 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();
}
}
2 回答
始终将KeyEvent调度到具有焦点的组件,鼠标位置与生成键事件的方式无关 .
您应该使用
Key Bindings
而不是使用KeyListener . 使用键绑定时,只要通过将绑定添加到JFrame的根窗格生成KeyStroke,就可以调用Action . 有关详细信息,请阅读Key Bindings上Swing教程中的部分 .现在在你创建的Action中听取“?” KeyStroke然后你可以:
使用
MouseInfo
类获取当前鼠标位置 .使用
SwingUtilities.convertPointFromScreen(...)
将鼠标点转换为相对于根窗格然后您可以使用
Conatiner.getComponentAt(...)
获取鼠标结束的实际组件一旦您知道该组件,您就可以显示您的帮助信息 .
我确信有更好的方法,但一个快速而肮脏的解决方案:
或者,如有必要:
然后只需
.addMouseListener(new HoverFocusListener())
到所有受影响的组件 .