Java Swing:如何在JComboBox项目上添加鼠标悬停文本?

20
在Swing中,有没有一种方法可以为JComboBox中的每个项目定义鼠标悬停文本(或工具提示文本)?
5个回答

23

这里有一个比已经给出的ToolTipComboBox答案更好的方法。

首先,创建一个自定义的ListCellRenderer

package com.example;

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class ComboboxToolTipRenderer extends DefaultListCellRenderer {
    List<String> tooltips;

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
                        int index, boolean isSelected, boolean cellHasFocus) {

        JComponent comp = (JComponent) super.getListCellRendererComponent(list,
                value, index, isSelected, cellHasFocus);

        if (-1 < index && null != value && null != tooltips) {
            list.setToolTipText(tooltips.get(index));
        }
        return comp;
    }

    public void setTooltips(List<String> tooltips) {
        this.tooltips = tooltips;
    }
}

然后像这样使用它:

JComboBox comboBox = new JComboBox();
ComboboxToolTipRenderer renderer = new ComboboxToolTipRenderer();
comboBox.setRenderer(renderer);
...
//make a loop as needed
comboBox.addItem(itemString);
tooltips.add(tooltipString);
...
renderer.setTooltips(tooltips);

如何设置工具提示的位置?如果工具提示漂浮在光标下方,那么列表上的工具提示就没有太多意义了。工具提示应该出现在与列表项相同的y位置上。有什么想法可以实现这一点吗? - micro
我使用了这个解决方案并观察到了一个缺陷,如果组合框包含一个空字符串。在这种情况下,相应的行几乎是不可见的(2像素)。当我存储JComboBox的原始渲染器并调用originalRenderer.getListCellRendererComponent(...)而不是super.getListCellRendererComponent(...)时,问题消失了。 - tniessen
@micro:在我的应用程序中,一个图片被显示为工具提示,因此我不能依赖于setToolTipText,并且不得不自己实现包括位置问题的工具提示机制。这是通过使用MouseInfo.getPointerInfo().getLocation()和适当的MouseAdapter来解决的,该MouseAdapter被添加到JList中。 - tniessen

8
我喜欢MountainX方案的简洁性,但不喜欢缺乏封装的问题。另外一种解决方案有更多组成部分,但它们非常简单且可重复使用。
一个接口:
public interface ToolTipProvider {
    public String getToolTip();
}

一个包装类:
public class ToolTipWrapper implements ToolTipProvider {
    final Object value;
    final String toolTip;

    public ToolTipWrapper(Object value, String toolTip) {
        this.value = value;
        this.toolTip = toolTip;
    }

    @Override
    public String getToolTip() {
        return toolTip; 
    }

    @Override
    public String toString() {
        return value.toString();
    }

}

以下是MountainX渲染器的一个变体:

public class ToolTipRenderer extends DefaultListCellRenderer {

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
         JComponent component = (JComponent) super.getListCellRendererComponent(list, value, index, isSelected,
                cellHasFocus);
         String tip = null;
         if (value instanceof ToolTipProvider) {
             ToolTipProvider ttp = (ToolTipProvider) value;
             tip = ttp.getToolTip();
         }
         list.setToolTipText(tip);
         return component;
    }
}

现在有添加功能:

combobox.addItem(new ToolTipWrapper(itemString,tooltipString) );

3
如果您的组合框不可编辑,请使用 setRenderer(ListCellRenderer)。如果它是可编辑的,请使用 setEditor(ComboBoxEditor),因为:
渲染器在JComboBox不可编辑时使用。如果它是可编辑的,则使用编辑器来呈现和编辑所选项目。

3

这是一段来自在线示例的代码,已经做了一些修正:

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxRenderer;

/**
 * @version 1.0 06/05/99
 */
public class ToolTipComboBox extends JFrame {

  /**
     * 
     */
    private static final long serialVersionUID = 2939624252688908292L;

String[] items = { "jw", "ja", "la" };

  String[] tooltips = { "Javanese ", "Japanese ", "Latin " };

  public ToolTipComboBox() {
    super("ToolTip ComboBox Example");

    JComboBox combo = new JComboBox(items);
    combo.setRenderer(new MyComboBoxRenderer());

    getContentPane().setLayout(new FlowLayout());
    getContentPane().add(combo);
  }

  class MyComboBoxRenderer extends BasicComboBoxRenderer {
    /**
     * 
     */
    private static final long serialVersionUID = 2746090194775905713L;

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
        int index, boolean isSelected, boolean cellHasFocus) {
      if (isSelected) {
        setBackground(list.getSelectionBackground());
        setForeground(list.getSelectionForeground());
        if (-1 < index) {
          list.setToolTipText(tooltips[index]);
        }
      } else {
        setBackground(list.getBackground());
        setForeground(list.getForeground());
      }
      setFont(list.getFont());
      setText((value == null) ? "" : value.toString());
      return this;
    }
  }

  public static void main(String args[]) {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception evt) {}

    ToolTipComboBox frame = new ToolTipComboBox();
    frame.addWindowListener(new WindowAdapter() {
      @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    frame.setSize(200, 140);
    frame.setVisible(true);
  }
}

如何设置工具提示的位置?如果工具提示像其他工具提示一样浮动在光标下方,那么列表上的工具提示就没有多大意义了。 工具提示应出现在与列表项相同的y位置。 有什么好的方法可以实现这一点吗? - micro

0

我从没尝试过,但你应该可以定义一个ListCellRenderer,并让它返回一个带有工具提示的JLabel或其他内容。


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