3

TableCellRendererセル内のマウスの位置に応じて異なるツールチップを表示したいカスタムがあります。私が直面している問題は、から呼び出されたときにgetWidth()常に返されることです。0getToolTipText

SSCCE は次のとおりです。

import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseEvent;

public class Sandbox {
  public static void main(String[] args) {
    JFrame testFrame = new JFrame("Test");
    testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    testFrame.setLayout(new BorderLayout());

    JTable testTable = new JTable(new Object[][]{{"Value 1", null}}, new Object[] {"Column 1", "Column 2"});
    testTable.getColumnModel().getColumn(1).setCellRenderer(new CustomCellRenderer());

    testFrame.add(new JScrollPane(testTable), BorderLayout.CENTER);
    testFrame.pack();
    testFrame.setLocationRelativeTo(null);
    testFrame.setVisible(true);
  }

  private static class CustomCellRenderer implements TableCellRenderer {
    private final JLabel renderer = new JLabel()
    {
      @Override
      protected void paintComponent(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(0, 0, getWidth(), getHeight());
        System.out.println("Width from paintComponent = " + getWidth());
      }

      @Override
      public String getToolTipText(MouseEvent event) {
        System.out.println("Width from getToolTipText = " + getWidth());
        return super.getToolTipText(event);
      }
    };

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                   boolean hasFocus, int row, int column)
    {
      return renderer;
    }
  }
}

paintComponentコンポーネントのサイズが変更され、正しい結果がメソッドから出力されていることがわかります。ただし、「列 2」のセルにマウスを合わせると、getToolTipTextメソッドは同じ値を出力しません。

以前にも似たような質問がありましたが、答えは一般的にComponentまだサイズが決まっていないというものです。私の場合、コンポーネントは明らかにサイズ変更されています。誰かがメソッドでgetWidth()戻る理由を説明できますか? これを行うより良い方法はありますか?0getToolTipText

4

2 に答える 2

3

JTable の getToolTipText() メソッドをオーバーライドします。

JTable testTable = new JTable(new Object[][]{{"Value 1", null}}, new Object[] {"Column 1", "Column 2"})
{
  @Override
  public String getToolTipText(MouseEvent event)
  {
    JTable table = (JTable)event.getSource();
    int column = table.columnAtPoint( event.getPoint() );

    if (column == 1)
    {
        int row = table.rowAtPoint( event.getPoint() );
        Rectangle r = table.getCellRect(row, column, false);
        Point p = new Point(event.getX() - r.x, event.getY() - r.y);
//          System.out.println("Width from getToolTipText = " + r.width);

        return p.toString();
    }

    return super.getToolTipText(event);
  }
};

レンダラーでツール チップを設定する場合、コードは getTableCellRenderComponent() メソッド内にある必要があります。この場合、MouseInfo クラスを使用して現在のマウスの位置を取得し、その位置を表のセルに相対的に変換する必要があります。何かのようなもの:

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                               boolean hasFocus, int row, int column)
{
    Point pointInTable = MouseInfo.getPointerInfo().getLocation();
    SwingUtilities.convertPointFromScreen(pointInTable, table);
    Rectangle r = table.getCellRect(row, column, false);
    Point p = new Point(pointInTable.x - r.x, pointInTable.y - r.y);
    table.setToolTipText(p.toString());

  return renderer;
}
于 2013-06-07T00:29:12.943 に答える
2

2 つの異なるコンテキストでgetWidth()同じ結果が表示されます。JLabel

  1. ではpaintComponent()、を呼び出して幅を計算するJLabelに追加されています。CellRendererPanevalidate()

  2. ではgetToolTipText()、テーブルによってアクセスされるラベルToolTipManagerは検証されていません。

CellRendererPane ここに使用例があります。

于 2013-06-07T00:35:15.933 に答える