类似工具提示的消息跟随光标箭头

3
我该如何在Swing和Java 7中获取一个小型消息(带有恒定背景,类似于工具提示),并跟随箭头光标? 我的意思是,类似于工具提示的消息不依赖于光标当前所在的组件,而是一段文本始终跟随光标移动且与其“固定”。

谢谢。


如何才能让它“不依赖光标所在位置,而是“固定”在光标箭头上”?你的话有自相矛盾之处。 - Oliver Watkins
也许,他的意思是 - 不依赖于鼠标当前所在的组件,而是一个始终跟随光标移动并与之同行的文本。 - R Kaja Mohideen
给@OliverWatkins:我确切地意味着R Kaja Mohideen所写的。我会编辑这个问题。 - Paolo M
2个回答

5
  • 据我所知,这可以通过使用Swing TimerPropertyChangeListener实现。

  • 也许有其他的通知器,需要在一定时间内延迟代码执行,并小心处理E(vent)D(ispath)T(hread)。

  • 如果要将ToolTip添加到包含其他JComponentsJPanel中,则需要使用SwingUtilities.convertXxx

  • 例如:

. enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToolTip;
import javax.swing.Timer;
import javax.swing.ToolTipManager;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

public class DynamicToolTipTest {

    private JPanel panel = new MyPanel();
    private JFrame frame = new JFrame("DynamicToolTipTest");

    public DynamicToolTipTest() {
        ToolTipManager ttm = ToolTipManager.sharedInstance();
        ttm.setInitialDelay(200);
        ttm.setDismissDelay(10000);
        panel.setToolTipText("Text 1");
        final Timer timer = new Timer(50, new ActionListener() {
            private int id = 1;

            @Override
            public void actionPerformed(ActionEvent e) {
                ++id;
                panel.setToolTipText("Text " + id);
            }
        });
        timer.start();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.pack();
        frame.setLocation(150, 100);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DynamicToolTipTest();
            }
        });
    }

    private static final class MyPanel extends JPanel {

        private static final long serialVersionUID = 1L;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 200);
        }

        @Override
        public JToolTip createToolTip() {
            final JToolTip tip = super.createToolTip();
            final PropertyChangeListener updater = new PropertyChangeListener() {
                @Override
                public void propertyChange(final PropertyChangeEvent e) {
                    if (e.getNewValue() != null) {
                        tip.setTipText((String) e.getNewValue());
                        tip.repaint();
                    }
                }
            };
            tip.addAncestorListener(new AncestorListener() {
                @Override
                public void ancestorAdded(AncestorEvent event) {
                    //start listening for tip text changes only after the tip 
                    //is displayed, i.e. the tip is added to the component hierarchy
                    MyPanel.this.addPropertyChangeListener(TOOL_TIP_TEXT_KEY, updater);
                }

                @Override
                public void ancestorRemoved(AncestorEvent event) {
                    //stop listening for tip text changes once the tip is no longer 
                    //displayed, i.e. the tip is removed from the component hierarchy
                    MyPanel.this.removePropertyChangeListener(TOOL_TIP_TEXT_KEY, updater);
                }

                @Override
                public void ancestorMoved(AncestorEvent event) {
                }
            });
            return tip;
        }
    }
}

请查看@Guillaume Polet发布的代码示例,其中包含使用SwingUtilities.convertXxx方法(每秒一次)的内容:https://dev59.com/YGnWa4cB1Zd3GeqP0W7p#12823177 - mKorbel
感谢您的回复。您的代码运行得非常好,但它并不符合我的需求(我必须说我描述得很糟糕...)。问题在于,即使光标悬停在设置了特定工具提示的其他“JComponent”上,我也希望消息保持可见。我将编辑答案的标题。 - Paolo M
通过使用SwingUtilities.convertXxx从JComponent转换到父级(例如JPanel),可以实现此目的。 - mKorbel
好的,我会尽快查看。谢谢。 - Paolo M
好的,我认为这是最好的解决方案。但是对我来说,没有“标准”的做法似乎有些奇怪!顺便说一下,谢谢。 - Paolo M

0
只需在您的组件中添加setToolTipText(String)即可。

1
请您能否详细阐述一下您的答案,并添加更多关于您提供的解决方案的描述? - abarisone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接