Swing/PointInsidePrefSize のバックアップ差分(No.5)
- バックアップ一覧
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/PointInsidePrefSize へ行く。
- 1 (2011-08-30 (火) 19:48:45)
- 2 (2011-09-16 (金) 18:45:29)
- 3 (2011-09-18 (日) 04:59:20)
- 4 (2012-01-27 (金) 17:13:57)
- 5 (2012-12-19 (水) 01:52:58)
- 6 (2014-11-29 (土) 01:50:26)
- 7 (2015-02-17 (火) 22:27:32)
- 8 (2016-12-16 (金) 14:23:39)
- 9 (2017-07-28 (金) 18:22:23)
- 10 (2018-02-24 (土) 19:51:30)
- 11 (2018-07-31 (火) 14:01:16)
- 12 (2020-08-04 (火) 21:01:25)
- 13 (2021-12-26 (日) 07:54:12)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JTableのセル内でリンクだけHover可能にする #navi(../) RIGHT:Posted by [[aterai]] at 2011-08-29 RIGHT:Posted by &author(aterai); at 2011-08-29 *JTableのセル内でリンクだけHover可能にする [#e6636e70] JTableのセル内ではなく、内部のリンク上にカーソルがきた場合だけHoverするように設定します。 -&jnlp; -&jar; -&zip; //#screenshot #ref(https://lh3.googleusercontent.com/-OQfktkzVBD4/Tlsepf4ePZI/AAAAAAAABBQ/bikhWupFHEk/s800/PointInsidePrefSize.png) **サンプルコード [#g63a443d] #code{{ #code(link){{ //@see SwingUtilities2.pointOutsidePrefSize(...) 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); Dimension itemSize = cell.getPreferredSize(); Insets i = ((JComponent)cell).getInsets(); Rectangle cellBounds = table.getCellRect(row, col, false); cellBounds.width = itemSize.width-i.right-i.left; cellBounds.translate(i.left, i.top); return cellBounds.contains(p); } private boolean isRollover = false; private static boolean isURLColumn(JTable table, int column) { return column>=0 && table.getColumnClass(column).equals(URL.class); } @Override public void mouseMoved(MouseEvent e) { JTable table = (JTable)e.getSource(); Point pt = e.getPoint(); 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(); } @Override public void mouseExited(MouseEvent e) { JTable table = (JTable)e.getSource(); if(isURLColumn(table, col)) { table.repaint(table.getCellRect(row, col, false)); row = -1; col = -1; isRollover = false; } } @Override public void mouseClicked(MouseEvent e) { JTable table = (JTable)e.getSource(); Point pt = e.getPoint(); int ccol = table.columnAtPoint(pt); if(isURLColumn(table, ccol) && pointInsidePrefSize(table, pt)) { int crow = table.rowAtPoint(pt); URL url = (URL)table.getValueAt(crow, ccol); System.out.println(url); //try{ // Desktop.getDesktop().browse(url.toURI()); //}catch(Exception ex) { // ex.printStackTrace(); //} try{ Desktop.getDesktop().browse(url.toURI()); }catch(Exception ex) { ex.printStackTrace(); } } } }} **解説 [#c629ee2d] SwingUtilities2.pointOutsidePrefSize(...)を参考にして、セルの表示に使用するコンポーネント(JLabel)の標準サイズ(幅)内にカーソルがあるかどうかを比較するメソッドを作成しています。JTableに追加したMouseListenerでこれを使用し、URLの文字列をHoverするか、それがクリックされたかを判断しています。 **参考リンク [#h06368d9] -[[JTableのセルにHyperlinkを表示>Swing/HyperlinkInTableCell]] -[[Htmlで修飾した文字列のクリップ>Swing/ClippedHtmlLabel]] -[[JTableで文字列をクリックした場合だけセルを選択状態にする>Swing/TableFileList]] -[http://java.net/projects/swingset3/sources/svn/content/trunk/SwingSet3/src/com/sun/swingset3/demos/table/HyperlinkCellRenderer.java SwingSet3: HyperlinkCellRenderer.java] **コメント [#r6f7ffe9] - SwingSet3のHyperlinkCellRenderer.javaを参考にして、再描画するセルの範囲を最適化、ついでにHyperlinkCellRenderer.java#checkIfPointInsideHyperlink(Point p)ではセルコンポーネントの内余白(Insets)が考慮されていないので修正。 -- [[aterai]] &new{2011-09-16 (金) 18:45:29}; #comment