如何在单元格编辑开始时关闭表格中的所有工具提示?

时间:2012-01-19 05:03:27

标签: java swing jtable tooltip

我通过覆盖JTable继承的JComponent方法在我的JTable中启用了工具提示:

public String getToolTipText(MouseEvent e) { ... }

现在,假设用户在单元格上盘旋,出现工具提示,然后他开始编辑单元格,我想强行关闭工具提示。

目前,工具提示只是挂起,直到我使用ToolTipManager#setDismissDelay指定的值到期。工具提示有时会模糊正在编辑的单元格的视图,这就是为什么我想在表格上的任何单元格进入编辑模式时忽略它。

我尝试了以下方法(这是伪代码)

public String getToolTipText(MouseEvent e)
{
    if(table-is-editing)
        return null;
    else
        return a-string-to-display-in-the-tooltip;
}

当然,这只会导致在编辑模式下显示表的工具提示非常好。我知道这不起作用,但它更像是在黑暗中拍摄。

5 个答案:

答案 0 :(得分:6)

您可以使用以下代码显示/隐藏工具提示:

//Action toolTipAction = component.getActionMap().get("postTip");
Action toolTipAction = component.getActionMap().get("hideTip");

if (toolTipAction != null)
{
    ActionEvent ae = new ActionEvent(component, ActionEvent.ACTION_PERFORMED, "");
    toolTipAction.actionPerformed( ae );
}

您可能会覆盖JTable的prepareCellEditor(...)方法来添加此代码,它应该在显示编辑器之前隐藏任何工具提示。

编辑:

在回应Kleopatra的评论时,我添加以下内容以确保将Action添加到ActionMap中:

table.getInputMap().put(KeyStroke.getKeyStroke("pressed F2"), "dummy");
ToolTipManager.sharedInstance().registerComponent( table );

答案 1 :(得分:6)

即将评论"你的" - 但是如果没有在开始编辑时隐藏工具提示,可能会发生一个用例: - )

一些事实:

  • 工具提示隐藏在mouseExit和focusLost上使用ToolTipManager注册的组件
  • 开始编辑时,编辑组件获得焦点,因此工具提示会自动隐藏
  • 默认情况下,JTable 为编辑组件提供焦点是通过键入单元格来启动编辑(而不是双击或F2):在这种情况下,不会触发focusLost因此工具提示没有隐藏
  • ToolTipManager确实安装了一个可能被重复使用的hideAction(如@camickr所述)。 但是 - 仅当组件具有WHEN_FOCUSED类型的inputMap时才会安装该操作。 JTable的情况并非如此(所有绑定都在WHEN_ANCESTOR中)

因此需要进行一些调整才能实现所需的行为,下面是一段代码片段(请注意自己:在SwingX中实现: - )

JTable table = new JTable(new AncientSwingTeam()) {

    {
        // force the TooltipManager to install the hide action
        getInputMap().put(KeyStroke.getKeyStroke("ctrl A"), 
             "just some dummy binding in the focused InputMap");
        ToolTipManager.sharedInstance().registerComponent(this);

    }

    @Override
    public boolean editCellAt(int row, int column, EventObject e) {
        boolean editing = super.editCellAt(row, column, e);
        if (editing && hasFocus()) {
            hideToolTip();
        }
        return editing;
    }

    private void hideToolTip() {
        Action action = getActionMap().get("hideTip");
        if (action != null) {
            action.actionPerformed(new ActionEvent(
                this, ActionEvent.ACTION_PERFORMED, "myName"));
        }
    }

};

答案 2 :(得分:1)

结帐JTable tutorial。特别是webstart。有两个带有工具提示的可编辑列 - “Sport”和“Vegetarian”工作得很好。您使用的是自定义单元格渲染器吗?

答案 3 :(得分:1)

这对我有用,看起来比使用动作更简单:

ToolTipManager.sharedInstance().mouseExited(new MouseEvent(myJframe, 0, 0, 0, 0, 0, 0, 0, 0, false, 0));

这似乎隐藏了指定JFrame中显示的任何工具提示。

答案 4 :(得分:0)

使用JDK 1.6,当显示单元格工具提示时,用户无法使用键盘扩展所选行的范围。上面提出的解决方案也很好地解决了这个问题。这是代码:

public class ToolTipTable extends JTable
{
/**
 * Constructor
 */
public ToolTipTable()
{
    super();

    // force the TooltipManager to install the hide action
    getInputMap().put(KeyStroke.getKeyStroke("ctrl A"),
            "just some dummy binding in the focused InputMap");
    ToolTipManager.sharedInstance().registerComponent(this);

    //hide the tool tip when row selection changes
    this.getSelectionModel().addListSelectionListener(
            new ListSelectionListener()
            {
                @Override
                public void valueChanged(ListSelectionEvent e)
                {
                    hideToolTip();
                }
            });
}

/**
 * Make the cell tool tip show the contents of the cell. (Useful if the
 * cell contents are wider than the column.)
 */
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row,
        int column)
{
    Component c = super.prepareRenderer(renderer, row, column);
    if (c instanceof JComponent)
    {
        JComponent jc = (JComponent) c;
        Object valueObj = getValueAt(row, column);
        if (valueObj != null)
        {
             jc.setToolTipText(getValueAt(row, column).toString());
        }
    }
    return c;
}

/**
 * 
 */
private void hideToolTip()
{
    Action action = getActionMap().get("hideTip");
    if (action != null)
    {
        action.actionPerformed(new ActionEvent(this,
                ActionEvent.ACTION_PERFORMED, "myName"));
    }
}
}