Swing/TranslucentScrollBar のバックアップの現在との差分(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/TranslucentScrollBar へ行く。
- 1 (2013-05-20 (月) 17:18:43)
- 2 (2014-03-04 (火) 20:19:29)
- 3 (2014-05-27 (火) 15:59:34)
- 4 (2014-09-29 (月) 17:43:30)
- 5 (2014-11-22 (土) 03:59:58)
- 6 (2015-01-16 (金) 21:18:52)
- 7 (2015-02-19 (木) 18:40:41)
- 8 (2015-04-09 (木) 14:55:22)
- 9 (2015-11-29 (日) 21:37:26)
- 10 (2015-11-30 (月) 00:47:49)
- 11 (2017-05-23 (火) 14:23:40)
- 12 (2017-07-31 (月) 16:13:03)
- 13 (2018-02-24 (土) 19:51:30)
- 14 (2018-08-01 (水) 21:32:20)
- 15 (2019-07-08 (月) 17:21:08)
- 16 (2021-03-17 (水) 01:58:50)
- 追加された行はこの色です。
- 削除された行はこの色です。
--- category: swing folder: TranslucentScrollBar title: JScrollBarを半透明にする tags: [JScrollBar, JViewport, JScrollPane, Translucent, LayoutManager] author: aterai pubdate: 2013-05-20T17:18:43+09:00 description: 半透明のJScrollBarを作成して、JViewport内部に配置します。 image: https://lh3.googleusercontent.com/-X8o390yxqhI/UZjhjkgUrkI/AAAAAAAABsY/Aajtim-5-uE/s800/TranslucentScrollBar.png hreflang: href: https://java-swing-tips.blogspot.com/2015/03/create-translucent-jscrollbar.html lang: en --- * 概要 [#hce3a1ca] * 概要 [#summary] 半透明の`JScrollBar`を作成して、`JViewport`内部に配置します。 #download(https://lh3.googleusercontent.com/-X8o390yxqhI/UZjhjkgUrkI/AAAAAAAABsY/Aajtim-5-uE/s800/TranslucentScrollBar.png) * サンプルコード [#t5cb201e] * サンプルコード [#sourcecode] #code(link){{ public JComponent makeTranslucentScrollBar(JComponent c) { JScrollPane scrollPane = new JScrollPane(c) { @Override public boolean isOptimizedDrawingEnabled() { return false; // JScrollBar is overlap } @Override public boolean isOptimizedDrawingEnabled() { return false; // JScrollBar is overlap } }; scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setComponentZOrder(scrollPane.getVerticalScrollBar(), 0); scrollPane.setComponentZOrder(scrollPane.getViewport(), 1); scrollPane.getVerticalScrollBar().setOpaque(false); scrollPane.setLayout(new ScrollPaneLayout() { @Override public void layoutContainer(Container parent) { JScrollPane scrollPane = (JScrollPane)parent; JScrollPane scrollPane = (JScrollPane) parent; Rectangle availR = scrollPane.getBounds(); availR.x = availR.y = 0; Insets insets = parent.getInsets(); availR.x = insets.left; availR.y = insets.top; availR.width -= insets.left + insets.right; availR.height -= insets.top + insets.bottom; availR.width -= insets.left + insets.right; availR.height -= insets.top + insets.bottom; Rectangle vsbR = new Rectangle(); vsbR.width = 12; vsbR.width = 12; vsbR.height = availR.height; vsbR.x = availR.x + availR.width - vsbR.width; vsbR.y = availR.y; if(viewport != null) { if (viewport != null) { viewport.setBounds(availR); } if(vsb != null) { if (vsb != null) { vsb.setVisible(true); vsb.setBounds(vsbR); } } }); scrollPane.getVerticalScrollBar().setUI(new BasicScrollBarUI() { private final Dimension d = new Dimension(); private final Color defaultColor = new Color(220, 100, 100, 100); private final Color draggingColor = new Color(200, 100, 100, 100); private final Color rolloverColor = new Color(255, 120, 100, 100); @Override protected JButton createDecreaseButton(int orientation) { return new JButton() { @Override public Dimension getPreferredSize() { return d; } }; return new ZeroSizeButton(); } @Override protected JButton createIncreaseButton(int orientation) { return new JButton() { @Override public Dimension getPreferredSize() { return d; } }; return new ZeroSizeButton(); } @Override protected void paintTrack(Graphics g, JComponent c, Rectangle r) {} private final Color defaultColor = new Color(220,100,100,100); private final Color draggingColor = new Color(200,100,100,100); private final Color rolloverColor = new Color(255,120,100,100); @Override protected void paintTrack(Graphics g, JComponent c, Rectangle r) { /* empty */ } @Override protected void paintThumb(Graphics g, JComponent c, Rectangle r) { Color color; JScrollBar sb = (JScrollBar)c; if(!sb.isEnabled() || r.width>r.height) { JScrollBar sb = (JScrollBar) c; if (!sb.isEnabled() || r.width > r.height) { return; }else if(isDragging) { } else if (isDragging) { color = draggingColor; }else if(isThumbRollover()) { } else if (isThumbRollover()) { color = rolloverColor; }else{ } else { color = defaultColor; } Graphics2D g2 = (Graphics2D)g.create(); Graphics2D g2 = (Graphics2D) g.create(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(color); g2.fillRect(r.x,r.y,r.width-1,r.height-1); g2.fillRect(r.x, r.y, r.width - 1, r.height - 1); g2.setPaint(Color.WHITE); g2.drawRect(r.x,r.y,r.width-1,r.height-1); g2.drawRect(r.x, r.y, r.width - 1, r.height - 1); g2.dispose(); } @Override protected void setThumbBounds(int x, int y, int width, int height) { super.setThumbBounds(x, y, width, height); //scrollbar.repaint(x, 0, width, scrollbar.getHeight()); // scrollbar.repaint(x, 0, width, scrollbar.getHeight()); scrollbar.repaint(); } }); return scrollPane; } }} * 解説 [#aa85f74b] 上記のサンプルでは、`JScrollBar`の増減ボタンのサイズを`0`、トラックを透明、つまみを半透明にして、`JViewport`内部に配置しています。 * 解説 [#explanation] 上記のサンプルでは、`JScrollBar`の増減ボタンのサイズを非表示、トラックを透明、つまみを半透明にして、`JViewport`内部に配置しています。 - `ScrollPaneLayout#layoutContainer(...)`をオーバーライドして、`JScrollBar`を`JViewport`の内部にオーバーラップするように配置 -- `scrollPane.setComponentZOrder(...)`で、`JScrollBar`と`JViewport`の`Z`軸の順序を変更 - `ScrollPaneLayout#layoutContainer(...)`をオーバーライドして`JScrollBar`を`JViewport`の内部にオーバーラップするように配置 -- `scrollPane.setComponentZOrder(...)`で`JScrollBar`と`JViewport`の`Z`軸の順序を変更 - `BasicScrollBarUI#createDecreaseButton()`、`BasicScrollBarUI#createIncreaseButton()`をオーバーライドして増減ボタンのサイズを`0`に設定 -- [[JScrollBarのArrowButtonを非表示にする>Swing/ArrowButtonlessScrollBar]] - `BasicScrollBarUI#paintTrack()`をオーバーライドしてトラックを非表示 -- トラックにつまみの残像が残るので、`BasicScrollBarUI#setThumbBounds`をオーバーライドして`JScrollBar`全体を再描画 -- トラックにつまみの残像が残るので`BasicScrollBarUI#setThumbBounds`をオーバーライドして`JScrollBar`全体を再描画 - `BasicScrollBarUI#paintThumb()`をオーバーライドして半透明のつまみを描画 - つまみ描画のチラつき防止のため`JScrollPane#isOptimizedDrawingEnabled()`が`false`を返すようにオーバーライド -- このサンプルでは横スクロールバーの表示、カラムヘッダの表示に未対応 --- [[JScrollBarをJTable上に重ねて表示するJScrollPaneを作成する>Swing/OverlappedScrollBar]] - 注: -- %%`WindowsLookAndFeel`などでつまみの描画がチラつく?%% -- %%`JTextArea`などをこのサンプルの`JViewport`に配置すると、`Caret`の点滅や、文字列の選択などでつまみの描画が乱れる%% -- %%`JList`などの選択でも、つまみの描画が乱れる%% --- %%`ListSelectionListener`や、`FocusListener`を追加して再描画することで回避%% -- `JScrollPane#isOptimizedDrawingEnabled()`が`false`を返すようにオーバーライドして回避 -- 横スクロールバーの表示に未対応 * 参考リンク [#i4a3affa] * 参考リンク [#reference] - [http://www.oracle.com/technetwork/java/painting-140037.html "Optimized" Drawing - Painting in AWT and Swing] - [[JScrollBarをJTable上に重ねて表示するJScrollPaneを作成する>Swing/OverlappedScrollBar]] - [[JScrollBarのArrowButtonを非表示にする>Swing/ArrowButtonlessScrollBar]] * コメント [#p0420684] - `ScrollPaneLayout`を変更してオーバーラップするより、`JLayer`などを使ってドラッグ可能な矩形を描画する方が簡単かもしれない…。 -- [[aterai]] &new{2013-05-20 (月) 17:20:39}; * コメント [#comment] #comment - `ScrollPaneLayout`を変更してオーバーラップするより、`JLayer`などを使ってドラッグ可能な矩形を描画する方が簡単かもしれない…。 -- &user(aterai); &new{2013-05-20 (月) 17:20:39}; -- `JLayer`を使用するサンプルを追加: [[JScrollPane上にマウスカーソルが存在する場合のみJScrollBarを表示する>Swing/ScrollBarOnHover]] -- &user(aterai); &new{2017-07-31 (月) 16:12:57}; #comment