Swing/ExplorerLikeTable のバックアップ(No.28)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/ExplorerLikeTable へ行く。
- 1 (2007-03-15 (木) 23:37:33)
- 2 (2007-03-20 (火) 18:22:49)
- 3 (2007-03-26 (月) 20:41:27)
- 4 (2007-03-27 (火) 05:12:43)
- 5 (2007-07-27 (金) 13:09:35)
- 6 (2008-03-12 (水) 19:31:49)
- 7 (2008-06-24 (火) 12:54:25)
- 8 (2008-06-24 (火) 14:17:14)
- 9 (2010-01-01 (金) 00:53:27)
- 10 (2010-01-05 (火) 17:06:03)
- 11 (2010-01-07 (木) 16:58:24)
- 12 (2010-03-03 (水) 18:37:36)
- 13 (2010-03-25 (木) 18:35:21)
- 14 (2011-03-20 (日) 17:02:39)
- 15 (2012-10-20 (土) 04:31:21)
- 16 (2013-02-20 (水) 15:23:47)
- 17 (2013-02-27 (水) 13:52:36)
- 18 (2013-07-26 (金) 01:53:12)
- 19 (2013-08-20 (火) 14:22:06)
- 20 (2014-03-26 (水) 16:06:53)
- 21 (2015-01-15 (木) 15:22:28)
- 22 (2015-03-19 (木) 16:31:29)
- 23 (2016-05-27 (金) 13:14:02)
- 24 (2016-09-06 (火) 13:42:38)
- 25 (2017-10-19 (木) 15:26:54)
- 26 (2018-08-19 (日) 17:46:19)
- 27 (2018-10-30 (火) 16:36:23)
- 28 (2018-12-21 (金) 14:08:17)
- 29 (2020-11-22 (日) 01:04:55)
- 30 (2023-01-25 (水) 14:39:45)
- 31 (2024-02-14 (水) 23:39:51)
- category: swing folder: ExplorerLikeTable title: JTableのセルをエクスプローラ風に表示する tags: [JTable, TableCellRenderer, JLabel, Focus] author: aterai pubdate: 2006-07-17T08:23:31+09:00 description: セルの中にアイコンと文字列を配置し、エクスプローラ風に見えるよう、文字列だけにフォーカスをかけます。 image:
概要
セルの中にアイコンと文字列を配置し、エクスプローラ風に見えるよう、文字列だけにフォーカスをかけます。
Screenshot
Advertisement
サンプルコード
class TestRenderer extends Box implements TableCellRenderer {
private final Border emptyBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1);
private final ImageIcon nicon;
private final ImageIcon sicon;
private final JLabel textLabel;
private final JLabel iconLabel;
public TestRenderer(JTable table) {
super(BoxLayout.X_AXIS);
textLabel = new JLabel("dummy");
textLabel.setOpaque(true);
textLabel.setBorder(emptyBorder);
nicon = new ImageIcon(getClass().getResource("wi0063-16.png"));
FilteredImageSource fis = new FilteredImageSource(
nicon.getImage().getSource(), new SelectedImageFilter());
sicon = new ImageIcon(createImage(fis));
iconLabel = new JLabel(nicon);
iconLabel.setBorder(BorderFactory.createEmptyBorder());
table.setRowHeight(Math.max(textLabel.getPreferredSize().height,
iconLabel.getPreferredSize().height));
add(iconLabel);
add(textLabel);
add(Box.createHorizontalGlue());
}
@Override public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int column) {
textLabel.setText(Objects.toString(value, ""));
FontMetrics fm = table.getFontMetrics(table.getFont());
int swidth = fm.stringWidth(textLabel.getText()) + textLabel.getInsets().left
+ textLabel.getInsets().right;
int cwidth = table.getColumnModel().getColumn(column).getWidth()
-iconLabel.getPreferredSize().width;
textLabel.setPreferredSize(new Dimension(swidth > cwidth ? cwidth : swidth, 0));
if (isSelected) {
textLabel.setForeground(table.getSelectionForeground());
textLabel.setBackground(table.getSelectionBackground());
} else {
textLabel.setForeground(table.getForeground());
textLabel.setBackground(table.getBackground());
}
if (hasFocus) {
textLabel.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
} else {
textLabel.setBorder(emptyBorder);
}
textLabel.setFont(table.getFont());
iconLabel.setIcon(isSelected?sicon:nicon);
return this;
}
private static class SelectedImageFilter extends RGBImageFilter {
public SelectedImageFilter() {
canFilterIndexColorModel = false;
}
@Override public int filterRGB(int x, int y, int argb) {
//Color color = new Color(argb, true);
//float[] array = new float[4];
//color.getComponents(array);
//return new Color(array[0] * .5f, array[1] * .5f, array[2], array[3]).getRGB();
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
return (argb & 0xff0000ff) | ((r >> 1) << 16) | ((g >> 1) << 8);
}
}
}
View in GitHub: Java, Kotlin解説
Windows Explorer
(ファイルシステム・エクスプローラ)の詳細表示風にするため、以下のような設定をしています。
- セル間の罫線を非表示(
JTable#setShowHorizontalLines
,JTable#setShowVerticalLines
) - ひとつのセルの中でアイコンと文字列を表示するセルレンダラーを作成
- フォーカスが
JTable
に無い場合、選択されたセルの背景色をパネルの背景色に変更
このレンダラーでは、アイコンと文字列を別々のJLabel
で作成して並べることで、JList#putClientProperty("List.isFileList", Boolean.TRUE)
した場合のように、フォーカスはセルではなく文字列だけに点線で掛かるようになっています。
選択時にはセル全体の背景色を変更するのではなく、文字列を表示しているJLabel
の背景色を変更し、そのPreferredSize
を文字列の長さまで縮小して右側に余白を作成しています。
Windows Explorer
との相違点- アイコンと文字列以外の場所(セル内)をクリックしても、選択できてしまう
WindowsLookAndFeel
でのJFileChooser
は、JTable.putClientProperty("Table.isFileList", Boolean.TRUE)
を使用?- JTableで文字列をクリックした場合だけセルを選択状態にする
- マウスドラッグによる範囲指定で選択できない
ソートすると選択状態がクリアされてしまうTableRowSorter
では標準で選択状態を維持するようになった- TableSorterでソートしても選択状態を維持
Tabキー、矢印キーによる選択状態の移動がおかしい- 編集不可
- アイコンと文字列以外の場所(セル内)をクリックしても、選択できてしまう