使用Swing组件作为内容的自定义Java工具提示不会显示

我试图在组件的工具提示中显示多个图像,找到createToolTip()并实现一个自定义,添加如下所需的组件:

 setComponent(component); JPanel images = new JPanel(null); images.setLayout(new BoxLayout(images, BoxLayout.X_AXIS)); for(ImageIcon icon:myIcons) { images.add(new JLabel(icon)); } JPanel content = new JPanel(new BorderLayout()); content.add(new JLabel(title), BorderLayout.NORTH); content.add(new JLabel(description)); content.add(images, BorderLayout.SOUTH); add(content); 

但是,我看到的只是一个小点,表示工具提示已显示,但不知何故,大小被忽略。 我错过了实施自定义工具提示的内容?

基本的“问题”是JToolTip

  • is-not design as a container,它只是偶然的容器,因为JComponent是。 对于Swing“not-container”,ui-delegate有责任充当LayoutManager。
  • 是不够丰富,它可以处理纯文本(至少与紧急门html,这是@Andrew的最爱:-)

绕过这些限制基本上是推动小部件几乎超越边缘。 一个干净的解决方案将滚动一个新组件..另一方面,OP已经找到螺丝进行调整。 唯一可以略微改进的是既不调用setXXSize,也不设置自定义ui。 相反,通过重写getXXSize()使其行为像容器:

 @Override public Dimension getPreferredSize() { if (getLayout() != null) { return getLayout().preferredLayoutSize(this); } return super.getPreferredSize(); } 

工具提示可以呈现HTML。 如果你可以为图像形成URL(如果它们是在内存中生成的,则不实用,但通常也可以这样做),编写一些可以加载图像的HTML并使用该HTML作为工具提示是一件容易的事。


例如

MultiIconToolTip

 import javax.swing.*; class MultiIconToolTip { public static void main(String[] args) throws Exception { final String html = "" + " " + "" + "

Look Ma, no hands!"; SwingUtilities.invokeLater( new Runnable() { public void run() { JLabel hover = new JLabel("Point at me!"); hover.setToolTipText(html); JOptionPane.showMessageDialog(null, hover); } }); } }

我建议使用JWindow或un_decorated JDialog作为弹出窗口(默认用于JCalendarJDatePicker )而不是JTooltip ,以便更好地输出到GUI实现半透明和形状Windows

这可能听起来很愚蠢但是,你试过为JPanel设置边界吗?

 setBounds(100, 100, 150, 50); 

您可以尝试在BorderLayout 设置组件之间的间隙

 JPanel content = new JPanel(new BorderLayout(1,1)); 

基本上缺少两件事。 首先, JToolTip扩展了JComponent ,与JPanel不同,它没有默认布局。 要在工具提示中拉伸content ,请使用BorderLayout

 setLayout(new BorderLayout()); 

第二个问题是尺寸。 ToolTipManager尊重工具提示的首选大小。 BorderLayout计算大小时, ToolTipUI忽略它。 因此,有两种选择:手动设置首选大小…

 setPreferredSize(content.getPreferredSize()); 

请注意,这不会使布局过时; 否则,你得到一个尺寸合适的空工具提示。

…或子类ToolTipUI来尊重布局,这就是我的用法。 结果代码是:

 setComponent(StadtLabel.this); JPanel images = new JPanel(null); waren.setLayout(new BoxLayout(waren, BoxLayout.X_AXIS)); for(ImageIcon icon:myIcons) { JLabel lbl = new JLabel(icon); } JPanel content = new JPanel(new BorderLayout()); content.add(new JLabel(title), BorderLayout.NORTH); content.add(new JLabel(description)); content.add(images, BorderLayout.SOUTH); setLayout(new BorderLayout()); add(content); setUI(new ToolTipUI() { @Override public Dimension getMinimumSize(JComponent c) { return c.getLayout().minimumLayoutSize(c); } @Override public Dimension getPreferredSize(JComponent c) { return c.getLayout().preferredLayoutSize(c); } @Override public Dimension getMaximumSize(JComponent c) { return getPreferredSize(c); } }); 

不要重新发明轮子试试这个: https : //github.com/timmolderez/balloontip 。 您可以将任何内容作为JComponent。