Swing/TranslucentList の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/TranslucentList へ行く。
- Swing/TranslucentList の差分を削除
--- category: swing folder: TranslucentList title: JListの選択色を半透明に設定する tags: [JList, ListCellRenderer, JScrollPane, JViewport] author: aterai pubdate: 2019-02-18T17:02:30+09:00 description: JListの選択色を半透明に設定、また背景色を透明にして親パネルの背景を透かして表示します。 image: https://drive.google.com/uc?id=1vKNT9-SB-DsPrTxPEVYwq8FHoKQ97DYZog --- * 概要 [#summary] `JList`の選択色を半透明に設定、また背景色を透明にして親パネルの背景を透かして表示します。 #download(https://drive.google.com/uc?id=1vKNT9-SB-DsPrTxPEVYwq8FHoKQ97DYZog) * サンプルコード [#sourcecode] #code(link){{ 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 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; } } }} * 解説 [#explanation] - `JList`、`JScrollPane`にアルファ値`0`で完全に透明な背景色を設定 - `JList`、`JScrollPane`、`JViewport`に`setOpaque(false)`を設定して透明化 -- `JList`を`setOpaque(true)`で不透明化した場合、`ListSelectionListener`などで選択が変更されたら再描画する必要がある -- `JViewport`を`setOpaque(true)`で不透明化した場合、`ChangeListener`でスクロールが発生したら再描画する必要がある - `ListCellRenderer`に`setOpaque(false)`を設定して透明化 -- `ListCellRenderer`の選択色を`paintComponent(...)`メソッドをオーバーライドして半透明で描画 * 参考リンク [#reference] - [[JListのアイテムを範囲指定で選択>Swing/RubberBanding]] -- 半透明の矩形選択はこちらのサンプルを参考 - [[JTableのヘッダを透明化>Swing/TransparentTableHeader]] -- セル選択の半透明化はこちらの`JTable`のサンプルを参考 * コメント [#comment] #comment #comment