我有一个应用程序使用JTextPane
基本上作为多行标签,可以居中文本并自动包装(居中是我不使用较轻的组件的原因,但JTextArea
会有同样的问题)。它被用作更大实体的一部分,它应该使用一个工具提示。但是,为包含的组件设置工具提示不适用于JTextPane
。其他组件按预期显示工具提示。
SSCCE:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
public class ToolTipTest {
ToolTipTest() {
JFrame frame = new JFrame("Tool tip test");
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel bg = new JPanel(new BorderLayout());
frame.add(bg);
bg.add(new JLabel("Tooltip shows here"), BorderLayout.NORTH);
JTextPane text = new JTextPane();
try {
text.getStyledDocument().insertString(0, "Lorem ipsum dolor sit"
+ " amet, consectetur adipiscielit, sed eiusmod tempor"
+ " incidunt ut labore et dolore magna aliqua.", null);
} catch (BadLocationException e) {
e.printStackTrace();
}
text.setEditable(false);
text.setFocusable(false);
bg.add(text);
bg.setToolTipText("A tooltip, that should show on both the label and the text");
// Works, but is ugly and results in visible change in tooltip when
// moving cursor between components
// text.setToolTipText("A tooltip, that should show on both the label and the text");
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ToolTipTest();
}
});
}
}
在上面的示例中,工具提示显示在JLabel
上,但不显示在JTextPane
上。我目前正在为文本窗格设置相同的工具提示文本作为解决方法,但是当用户将鼠标光标移动到组件顶部时,这会导致工具提示之间的可见切换。
有没有办法在JTextPane
上显示父组件的工具提示?
修改
我尝试重写getToolTipText()
方法并使用工具提示管理器注册组件,如评论中所建议的那样。这样,在文本窗格然后从父级获取工具提示文本的意义上。但是,视觉效果与我的解决方法完全相同。
答案 0 :(得分:4)
基本上,您需要代理工具提示功能,以便在请求时从父级传回值。
您还需要使用ToolTipManager
手动注册组件,否则不会要求提供工具提示...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
public class ParentToolTip {
public static void main(String[] args) {
new ParentToolTip();
}
public ParentToolTip() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextPane text = new JTextPane() {
@Override
public String getToolTipText() {
return ((JComponent) getParent()).getToolTipText();
}
@Override
public String getToolTipText(MouseEvent event) {
return ((JComponent) getParent()).getToolTipText(event);
}
};
try {
text.getStyledDocument().insertString(0, "Lorem ipsum dolor sit"
+ " amet, consectetur adipiscielit, sed eiusmod tempor"
+ " incidunt ut labore et dolore magna aliqua.", null);
} catch (BadLocationException e) {
e.printStackTrace();
}
ToolTipManager.sharedInstance().registerComponent(text);
JFrame frame = new JFrame("Testing");
JPanel panel = new JPanel(new BorderLayout());
panel.setToolTipText("This is not the tooltip your are looking for");
frame.setContentPane(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(text);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
答案 1 :(得分:2)
基于mKorbel的想法,我在组件组的顶部做了一个玻璃窗格样式覆盖。在我的例子中,所有组件只提供信息,不需要用户交互,因此玻璃窗格不会打扰调度事件。
我使用OverlayLayout
,因为它对我来说最简单和充分。应用于问题中的代码,ToolTipTest
构造函数将更改为:
ToolTipTest() {
JFrame frame = new JFrame("Tool tip test");
frame.setLocationByPlatform(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Holds the component group and the glass pane
JComponent content = new JPanel();
content.setLayout(new OverlayLayout(content));
frame.add(content);
JComponent glassPane = new JComponent(){};
content.add(glassPane);
final JPanel bg = new JPanel(new BorderLayout());
content.add(bg);
bg.add(new JLabel("Tooltip shows here"), BorderLayout.NORTH);
JTextPane text = new JTextPane();
try {
text.getStyledDocument().insertString(0, "The same tooltip also shows here", null);
} catch (BadLocationException e) {
e.printStackTrace();
}
text.setEditable(false);
text.setFocusable(false);
bg.add(text);
glassPane.setToolTipText("A tooltip, that shows on both the label and the text");
JLabel other = new JLabel("This component has another tooltip");
other.setToolTipText("Another tooltip");
frame.add(other, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
编辑:包含带有共享工具提示的组件组外部的标签,以区别于更典型的玻璃窗格使用。