Java 如果光标退出,如何在几秒钟后隐藏弹出窗口
我有一个弹出的Java 如果光标退出,如何在几秒钟后隐藏弹出窗口,java,swing,timer,cursor,hide,Java,Swing,Timer,Cursor,Hide,我有一个弹出的JDialog,它会显示3秒钟并进行处理。 它出现在光标位置,只有当光标退出弹出窗口时才需要处理 如果光标进入弹出窗口,计时器将停止并在退出时重新启动 但是我的第一个想法是使用dispose-定时器,它通过MouseListener启动和停止,但它不适用于某些JComponents,这会导致mouseExited() 我的第二个想法永远不会启动计时器 public void mouseExited( MouseEvent e ) { if(!Popup.this.getBo
JDialog
,它会显示3秒钟并进行处理。它出现在光标位置,只有当光标退出弹出窗口时才需要处理 如果光标进入弹出窗口,计时器将停止并在退出时重新启动 但是我的第一个想法是使用dispose-
定时器,它通过MouseListener
启动和停止,但它不适用于某些JComponent
s,这会导致mouseExited()
我的第二个想法永远不会启动计时器
public void mouseExited( MouseEvent e ) {
if(!Popup.this.getBounds().contains( e.getLocationOnScreen() )){
timer.start();
}
}
我不想将侦听器添加到弹出窗口中的每个组件。
有没有一个简单的方法可以做到这一点
例如:
public class Popup extends JDialog {
private static final long serialVersionUID = 1337L;
private final Timer timer = new Timer( 3000, new ActionListener() {
@Override
public void actionPerformed( ActionEvent e ) {
Popup.this.dispose();
System.exit( 0 );
}
});
public Popup() {
setBounds( 100, 100, 300, 300 );
addMouseListener( new PopupBehavior() );
getContentPane().setLayout( new BorderLayout() );
getContentPane().add( new JTextArea(), BorderLayout.NORTH );
getContentPane().add( new JSplitPane(0,new JPanel(), new JLabel("2")), BorderLayout.CENTER );
getContentPane().add( new JProgressBar(), BorderLayout.SOUTH );
getContentPane().add( new JLabel("west"), BorderLayout.WEST );
getContentPane().add( new JSpinner(), BorderLayout.EAST );
}
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
@Override
public void run() {
new Popup().setVisible( true );
}
});
}
private class PopupBehavior extends MouseAdapter {
@Override
public void mouseEntered( MouseEvent e ) {
System.out.println("mouseEntered");
timer.stop();
}
@Override
public void mouseExited( MouseEvent e ) {
System.out.println("mouseExited");
timer.start();
}
}
}
例如(据我所知,大多数JComponents
)都有Model
如果要从模型或从预定义的矩形中移出的鼠标启动javax.swing.Timer
如果鼠标返回到预定义的矩形
,则只需重新启动javax.swing.Timer
卓越的sugestion自JToolTip以来从jdk7开始,您可以使用JLayer装饰您的容器,并在其processMouseEvent中停止/启动计时器
class DisposingLayerUI extends LayerUI {
@Override
public void installUI(JComponent c) {
super.installUI(c);
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK
);
}
@Override
public void uninstallUI(JComponent c) {
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(0);
super.uninstallUI(c);
}
@Override
protected void processMouseEvent(MouseEvent e, JLayer l) {
if (e.getID() == MouseEvent.MOUSE_ENTERED) {
timer.stop();
} else if (e.getID() == MouseEvent.MOUSE_EXITED){
timer.start();
}
}
}
// to use in your code, do all init and then decorate the contentPane
...
setContentPane(new JLayer(getContentPane(), new DisposingLayerUI()));
对于较旧的版本,您可以使用项目中的层(它是当前开发的层)或手动实现全局侦听器,如《任何帮助》中的f.i.所示。@trashgod-您不是建议向每个孩子递归注册侦听器,是吗?只有在实际涉及到JSpinner
时才作为最后手段;您引用的AWTEventListener
看起来更有希望。@trashgod同意最后的办法:-)在沙盒上下文中可能是必要的,因为沙盒上下文不允许注册AWTEventListener。JLayer也使用它,但作为特权操作的核心是更多的随机想法,这一次与接收儿童鼠标事件无关;-)