TITLE:JTableのセル内でリンクだけHover可能にする
Posted by aterai at 2011-08-29

JTableのセル内でリンクだけHover可能にする

JTableのセル内ではなく、内部のリンク上にカーソルがきた場合だけHoverするように設定します。
  • category: swing folder: PointInsidePrefSize title: JTableのセル内でリンクだけHover可能にする tags: [JTable, TableCellRenderer, MouseListener, URL] author: aterai pubdate: 2011-08-29T14:18:50+09:00 description: JTableのセル内ではなく、内部のリンク上にカーソルがきた場合だけHoverするように設定します。 image: https://lh3.googleusercontent.com/-OQfktkzVBD4/Tlsepf4ePZI/AAAAAAAABBQ/bikhWupFHEk/s800/PointInsidePrefSize.png hreflang:
       href: https://java-swing-tips.blogspot.com/2009/02/hyperlink-in-jtable-cell.html
       lang: en

概要

JTableのセル内ではなく、内部のリンク上にカーソルがきた場合だけHoverするように設定します。
PointInsidePrefSize.png

サンプルコード

#spanend
#spandel
//@see SwingUtilities2.pointOutsidePrefSize(...)
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
// @see SwingUtilities2.pointOutsidePrefSize(...)
#spanend
private static boolean pointInsidePrefSize(JTable table, Point p) {
  int row = table.rowAtPoint(p);
  int col = table.columnAtPoint(p);
  TableCellRenderer tcr = table.getCellRenderer(row, col);
  Object value = table.getValueAt(row, col);
  Component cell = tcr.getTableCellRendererComponent(
      table, value, false, false, row, col);
    table, value, false, false, row, col);
  Dimension itemSize = cell.getPreferredSize();
  Insets i = ((JComponent) cell).getInsets();
  Rectangle cellBounds = table.getCellRect(row, col, false);
  cellBounds.width = itemSize.width;
  cellBounds.width = itemSize.width - i.right - i.left;
  cellBounds.translate(i.left, i.top);
  return cellBounds.contains(p);
}
#spanadd

#spanend
#spanadd
private static boolean isURLColumn(JTable table, int column) {
#spanend
  return column >= 0 && table.getColumnClass(column).equals(URL.class);
#spanadd
}
#spanend
#spanadd

#spanend
@Override public void mouseMoved(MouseEvent e) {
  JTable table = (JTable)e.getSource();
  JTable table = (JTable) e.getSource();
  Point pt = e.getPoint();
  if(pointInsidePrefSize(table, pt)) {
    row = table.rowAtPoint(pt);
    col = table.columnAtPoint(pt);
  }else{
  int prev_row = row;
  int prev_col = col;
  boolean prev_ro = isRollover;
  row = table.rowAtPoint(pt);
  col = table.columnAtPoint(pt);
  isRollover = isURLColumn(table, col) && pointInsidePrefSize(table, pt);
  if ((row == prev_row && col == prev_col && isRollover == prev_ro) ||
      (!isRollover && !prev_ro)) {
    return;
  }
  // >>>> HyperlinkCellRenderer.java
  Rectangle repaintRect;
  if (isRollover) {
    Rectangle r = table.getCellRect(row, col, false);
    repaintRect = prev_ro ?
      r.union(table.getCellRect(prev_row, prev_col, false)) : r;
  } else { //if (prev_ro) {
    repaintRect = table.getCellRect(prev_row, prev_col, false);
  }
  table.repaint(repaintRect);
  // <<<<
  //table.repaint();
#spanadd
}
#spanend
#spanadd

#spanend
#spanadd
@Override public void mouseExited(MouseEvent e)  {
#spanend
  JTable table = (JTable) e.getSource();
  if (isURLColumn(table, col)) {
    table.repaint(table.getCellRect(row, col, false));
    row = -1;
    col = -1;
    isRollover = false;
  }
  table.repaint();
}
#spandel
@Override public void mouseExited(MouseEvent e)  {
#spanend
  JTable table = (JTable)e.getSource();
  row = -1;
  col = -1;
  table.repaint();
#spandel
}
#spanend
#spanadd

#spanend
@Override public void mouseClicked(MouseEvent e) {
  JTable table = (JTable)e.getSource();
  JTable table = (JTable) e.getSource();
  Point pt = e.getPoint();
  if(pointInsidePrefSize(table, pt)) {
  int ccol = table.columnAtPoint(pt);
  if (isURLColumn(table, ccol) && pointInsidePrefSize(table, pt)) {
    int crow = table.rowAtPoint(pt);
    int ccol = table.columnAtPoint(pt);
    if(table.getColumnClass(ccol).equals(URL.class)) {
      URL url = (URL)table.getValueAt(crow, ccol);
      System.out.println(url);
      //try{
      //  Desktop.getDesktop().browse(url.toURI());
      //}catch(Exception ex) {
      //  ex.printStackTrace();
      //}
    URL url = (URL) table.getValueAt(crow, ccol);
    System.out.println(url);
    try {
      Desktop.getDesktop().browse(url.toURI());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

解説

SwingUtilities2.pointOutsidePrefSize(...)を参考にして、セルの表示に使用するコンポーネント(JLabel)の標準サイズ(幅)内にカーソルがあるかどうかを比較するメソッドを作成しています。JTableに追加したMouseListenerでこれを使用し、URLの文字列をHoverするか、それがクリックされたかを判断しています。

解説

  • SwingUtilities2.pointOutsidePrefSize(...)を参考にしてセルの表示に使用するコンポーネント(JLabel)の推奨サイズの範囲内にカーソルがあるかどうかを比較
  • JTableに追加したMouseListenerでこれを使用してURLの文字列をHover状態に変更するか、またはクリックされたかなどを判断する

参考リンク

参考リンク

コメント

コメント