JListの選択色を半透明に設定する
Total: 2644
, Today: 1
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
JList
の選択色を半透明に設定、また背景色を透明にして親パネルの背景を透かして表示します。
Screenshot
Advertisement
サンプルコード
JList<ListItem> list = new RubberBandSelectionList<>(model);
list.setOpaque(false);
list.setBackground(new Color(0x0, true));
list.setForeground(Color.WHITE);
// list.addListSelectionListener(e -> {
// SwingUtilities.getUnwrappedParent((Component) e.getSource()).repaint();
// });
JScrollPane scroll = new JScrollPane(list);
scroll.setBackground(new Color(0x0, true));
scroll.setOpaque(false);
scroll.setBorder(BorderFactory.createEmptyBorder());
scroll.setViewportBorder(BorderFactory.createEmptyBorder());
scroll.getViewport().setOpaque(false);
// scroll.getViewport().addChangeListener(e -> ((Component) e.getSource()).repaint());
JPanel panel = new JPanel(new BorderLayout()) {
private final TexturePaint texture = TextureUtils.createCheckerTexture(6);
@Override public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(texture);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
super.paintComponent(g);
}
};
panel.setBackground(Color.GREEN);
panel.setOpaque(false);
panel.add(scroll);
// ...
class ListItemListCellRenderer<E extends ListItem> implements ListCellRenderer<E> {
protected static final Color SELECTED_COLOR = new Color(50, 100, 255, 64);
private final JLabel label = new JLabel("", (Icon) null, SwingConstants.CENTER) {
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (SELECTED_COLOR.equals(getBackground())) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(SELECTED_COLOR);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
}
};
private final JPanel renderer = new JPanel(new BorderLayout());
private final Border focusBorder =
UIManager.getBorder("List.focusCellHighlightBorder");
private final Border noFocusBorder; // = UIManager.getBorder("List.noFocusBorder");
protected ListItemListCellRenderer() {
Border b = UIManager.getBorder("List.noFocusBorder");
if (Objects.isNull(b)) { // Nimbus???
Insets i = focusBorder.getBorderInsets(renderer);
b = BorderFactory.createEmptyBorder(i.top, i.left, i.bottom, i.right);
}
noFocusBorder = b;
label.setVerticalTextPosition(SwingConstants.BOTTOM);
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setForeground(renderer.getForeground());
label.setBackground(renderer.getBackground());
label.setBorder(noFocusBorder);
label.setOpaque(false);
renderer.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
renderer.add(label);
renderer.setOpaque(false);
}
@Override public Component getListCellRendererComponent(
JList<? extends E> list, E value, int index,
boolean isSelected, boolean cellHasFocus) {
label.setText(value.title);
label.setBorder(cellHasFocus ? focusBorder : noFocusBorder);
label.setIcon(value.icon);
if (isSelected) {
label.setForeground(list.getSelectionForeground());
label.setBackground(SELECTED_COLOR);
} else {
label.setForeground(list.getForeground());
label.setBackground(list.getBackground());
}
return renderer;
}
}
View in GitHub: Java, Kotlin解説
JList
、JScrollPane
にアルファ値0
で完全に透明な背景色を設定JList
、JScrollPane
、JViewport
にsetOpaque(false)
を設定して透明化JList
をsetOpaque(true)
で不透明化した場合、ListSelectionListener
などで選択が変更されたら再描画する必要があるJViewport
をsetOpaque(true)
で不透明化した場合、ChangeListener
でスクロールが発生したら再描画する必要がある
ListCellRenderer
にsetOpaque(false)
を設定して透明化ListCellRenderer
の選択色をpaintComponent(...)
メソッドをオーバーライドして半透明で描画
参考リンク
- JListのアイテムを範囲指定で選択
- 半透明の矩形選択はこちらのサンプルを参考
- JTableのヘッダを透明化
- セル選択の半透明化はこちらの
JTable
のサンプルを参考
- セル選択の半透明化はこちらの