Swing/ExplorerLikeTable のバックアップの現在との差分(No.3)
TITLE:JTableのセルをエクスプローラ風に表示する
JTableのセルをエクスプローラ風に表示する
編集者:Terai Atsuhiro~
作成日:2006-07-18
更新日:2024-02-14 (水) 23:39:51
概要
セルの中にアイコンと文字列を配置し、エクスプローラ風に見えるよう、文字列だけにフォーカスをかけます。Screenshot
Advertisement
概要
セルの中にアイコンと文字列を配置し、エクスプローラ風に見えるよう、文字列だけにフォーカスをかけます。サンプルコード
#spanend
#spanadd
class TestRenderer extends Box implements TableCellRenderer {
#spanend
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("JLabel");
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());
}
#spandel
#screenshot
#spanend
@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;
}
#spandel
**サンプルコード [#f06fb511]
#spanend
public TestRenderer(JTable table) {
super(BoxLayout.X_AXIS);
nicon = new ImageIcon(getClass().getResource("wi0063-16.png"));
FilteredImageSource fis = new FilteredImageSource(
nicon.getImage().getSource(),
new SelectedImageFilter());
sicon = new ImageIcon(createImage(fis));
iconLabel.setIcon(nicon);
textLabel = new MyLabel(table);
table.setRowHeight(textLabel.getPreferredSize().height);
}
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
textLabel.setText((value ==null) ? "" : value.toString());
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, 10000));
textLabel.setSelected(isSelected);
textLabel.setFocusedBorder(hasFocus);
textLabel.setFont(table.getFont());
iconLabel.setIcon((isSelected)?sicon:nicon);
removeAll();
add(iconLabel);
add(textLabel);
add(Box.createHorizontalGlue());
return this;
}
private static class SelectedImageFilter extends RGBImageFilter {
public SelectedImageFilter() {
canFilterIndexColorModel = false;
}
-&jnlp;
-&jar;
-&zip;
@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 & 0xFF_00_00_FF) | ((r >> 1) << 16) | ((g >> 1) << 8);
}
}
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin解説
エクスプローラの詳細のように表示するために、以下のような設定をしています。- セル間の罫線を非表示(JTable#setShowHorizontalLines, JTable#setShowVerticalLines)
解説
Windows Explorer
(ファイルシステム・エクスプローラ)の詳細表示風にするため、以下のような設定をしています。
- セル間の罫線を非表示(
JTable#setShowHorizontalLines
、JTable#setShowVerticalLines
) - ひとつのセルの中でアイコンと文字列を表示するセルレンダラーを作成
- フォーカスがJTableに無い場合、選択されたセルの背景色をパネルの背景色に変更
- フォーカスが
JTable
に無い場合選択されたセルの背景色をパネルの背景色に変更
JLabel
で作成して並べることでJList#putClientProperty("List.isFileList", Boolean.TRUE)
した場合のようにフォーカスはセルではなく文字列だけに点線で掛かるようになっています。
選択時にはセル全体の背景色を変更するのではなく、文字列を表示しているJLabelの背景色を変更し、そのPreferredSizeを文字列の長さまで縮小して右側に余白を作成しています。
選択時にはセル全体の背景色を変更するのではなく文字列を表示しているJLabel
の背景色を変更しそのPreferredSize
を文字列の長さまで縮小して右側に余白を作成しています。
- エクスプローラ風になっていない点
- アイコンと文字列以外の場所(セル内)をクリックしても、選択できてしまう
- JTableで文字列をクリックした場合だけセルを選択状態にする?
- WindowsLaFでのJFileChooserはどうやっているのだろうか?
- 矩形による範囲指定で選択することができない
- ソートすると選択状態がクリアされてしまう
- タブキー、矢印キーによる選択状態の移動がおかしい
- 編集不可
- アイコンと文字列以外の場所(セル内)をクリックしても、選択できてしまう
-
Windows Explorer
との相違点- アイコンと文字列以外の場所(セル内)をクリックしても選択できてしまう
-
WindowsLookAndFeel
でのJFileChooser
はJTable.putClientProperty("Table.isFileList", Boolean.TRUE)
を使用? - JTableで文字列をクリックした場合だけセルを選択状態にする
-
- マウスドラッグによる範囲指定で選択できない
-
ソートすると選択状態がクリアされてしまう-
TableRowSorter
では標準で選択状態を維持するようになった - TableSorterでソートしても選択状態を維持
-
-
Tabキー、矢印キーによる選択状態の移動がおかしい - 編集不可
- アイコンと文字列以外の場所(セル内)をクリックしても選択できてしまう