JComboBoxのドロップダウンリストで使用するJScrollBarを変更する
Total: 1452
, Today: 3
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JComboBox
のドロップダウンリストで使用する縦JScrollBar
の幅やスタイル、増減ボタンの有無などを変更します。
Screenshot
Advertisement
サンプルコード
JComboBox<String> combo2 = new JComboBox<String>(makeModel()) {
@Override public void updateUI() {
UIManager.put(KEY, BorderFactory.createLineBorder(Color.GRAY));
UIManager.put("ScrollBar.width", 10);
UIManager.put("ScrollBar.thumbHeight", 20);
UIManager.put("ScrollBar.minimumThumbSize", new Dimension(30, 30));
UIManager.put("ScrollBar.incrementButtonGap", 0);
UIManager.put("ScrollBar.decrementButtonGap", 0);
UIManager.put("ScrollBar.thumb", THUMB);
UIManager.put("ScrollBar.track", BACKGROUND);
UIManager.put("ComboBox.foreground", FOREGROUND);
UIManager.put("ComboBox.background", BACKGROUND);
UIManager.put("ComboBox.selectionForeground", SELECTION_FOREGROUND);
UIManager.put("ComboBox.selectionBackground", BACKGROUND);
UIManager.put("ComboBox.buttonDarkShadow", BACKGROUND);
UIManager.put("ComboBox.buttonBackground", FOREGROUND);
UIManager.put("ComboBox.buttonHighlight", FOREGROUND);
UIManager.put("ComboBox.buttonShadow", FOREGROUND);
super.updateUI();
setUI(new BasicComboBoxUI() {
@Override protected JButton createArrowButton() {
JButton b = new JButton(new ArrowIcon(BACKGROUND, FOREGROUND));
b.setContentAreaFilled(false);
b.setFocusPainted(false);
b.setBorder(BorderFactory.createEmptyBorder());
return b;
}
@Override protected ComboPopup createPopup() {
return new BasicComboPopup(comboBox) {
@Override protected JScrollPane createScroller() {
JScrollPane sp = new JScrollPane(list) {
@Override public void updateUI() {
super.updateUI();
getVerticalScrollBar().setUI(new WithoutArrowButtonScrollBarUI());
getHorizontalScrollBar().setUI(new WithoutArrowButtonScrollBarUI());
}
};
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED)
sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)
sp.setHorizontalScrollBar(null);
return sp;
}
};
}
});
Object o = getAccessibleContext().getAccessibleChild(0);
if (o instanceof JComponent) {
JComponent c = (JComponent) o;
c.setBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, Color.GRAY));
c.setForeground(FOREGROUND);
c.setBackground(BACKGROUND);
}
}
};
// ...
class ZeroSizeButton extends JButton {
@Override public Dimension getPreferredSize() {
return new Dimension();
}
}
class WithoutArrowButtonScrollBarUI extends BasicScrollBarUI {
@Override protected JButton createDecreaseButton(int orientation) {
return new ZeroSizeButton();
}
@Override protected JButton createIncreaseButton(int orientation) {
return new ZeroSizeButton();
}
@Override protected void paintTrack(Graphics g, JComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(trackColor);
g2.fill(r);
g2.dispose();
}
@Override protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
JScrollBar sb = (JScrollBar) c;
if (!sb.isEnabled()) {
return;
}
BoundedRangeModel m = sb.getModel();
if (m.getMaximum() - m.getMinimum() - m.getExtent() > 0) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color color;
if (isDragging) {
color = thumbDarkShadowColor.brighter();
} else if (isThumbRollover()) {
color = thumbLightShadowColor.brighter();
} else {
color = thumbColor;
}
g2.setPaint(color);
g2.fillRect(r.x + 1, r.y + 1, r.width - 2, r.height - 2);
g2.dispose();
}
}
}
View in GitHub: Java, Kotlin解説
- 上:
MetalLookAndFeel
デフォルトの編集不可JComboBox
- 下:
BasicComboBoxUI
をオーバーライドしてドロップダウンリストのスタイルなどを変更した編集不可JComboBox
BasicComboBoxUI#createPopup()
メソッドをオーバーライドしてBasicComboPopup
を生成、さらにそのBasicComboPopup#createScroller()
メソッドをオーバーライドしてJScrollPane
を生成、縦JScrollBar
などを取得し以下のUI
を変更JScrollBar
の幅:UIManager.put("ScrollBar.width", 10);
で変更JScrollBar
の増減ボタン: サイズ0
のJButton
を使用して非表示化JScrollBar
のハイライト色、背景色など:BasicScrollBarUI#paintThumb(...)
をオーバーライドして変更
参考リンク
- JScrollPaneの角を丸める
- 角を丸めるなどのコードを除去して簡素化したサンプルをこの記事に移動
- JScrollBar上にマウスカーソルが入ったらその幅を拡張する
- JScrollBarのArrowButtonを非表示にする
- ScrollBarの表示を変更