Swing/PaddingComboBox のバックアップの現在との差分(No.7)
TITLE:JComboBoxの内余白
JComboBoxの内余白
編集者:Terai Atsuhiro~
作成日:2007-05-28
更新日:2022-01-27 (木) 14:24:55
概要
JComboBox
のエディタなどに内余白を設定します。
Screenshot
Advertisement
概要
JComboBoxのエディタなどに内余白を設定します。サンプルコード
#spanend
#spanadd
static Border padding = BorderFactory.createEmptyBorder(0, 5, 0, 0);
#spanend
#spanadd
// ...
#spanend
#spanadd
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
#spanend
#spanadd
model.addElement("aaaaaaaaaaaaaaaaaaaaaaaaa");
#spanend
#spanadd
model.addElement("aaaabbb");
#spanend
#spanadd
model.addElement("aaaabbbcc");
#spanend
#spanadd
model.addElement("bbb1");
#spanend
#spanadd
model.addElement("bbb12");
#spanend
#spandel
#screenshot
#spanend
#spanadd
JComboBox<String> combo = new JComboBox<String>(model) {
#spanend
@Override public void updateUI() {
setRenderer(null);
super.updateUI();
ListCellRenderer<? super String> lcr = getRenderer();
setRenderer(new ListCellRenderer<String>() {
@Override public Component getListCellRendererComponent(
JList<? extends String> list, String value, int index,
boolean isSelected, boolean hasFocus) {
JLabel l = (JLabel) lcr.getListCellRendererComponent(
list, value, index, isSelected, hasFocus);
l.setBorder(padding);
return l;
}
});
// XXX JDK 1.7.0 ?: ((JLabel) lcr).setBorder(padding);
}
#spanadd
};
#spanend
#spanadd
View in GitHub: Java, Kotlinサンプルコード
#spanend
#spandel
//Border padding = BorderFactory.createEmptyBorder(0,5,0,0);
#spanend
#spandel
Border padding = BorderFactory.createMatteBorder(0,5,0,0,new Color(1f,.9f,.9f));
#spanend
#spanadd
* 解説 [#explanation]
#spanend
#spanadd
上記のサンプルでは、`JComboBox`に`Border`(`EmptyBorder`と`MatteBorder`を切り替え可能)を設定した`ListCellRenderer`を設定して、ドロップダウンリストの左余白をすこし広げています。`JComboBox`が編集不可の場合、エディタ部分もこの余白が自動的に適用されます。
#spanend
#spandel
final ListCellRenderer lcr = combo00.getRenderer();
#spanend
#spandel
((JLabel)lcr).setBorder(padding);
#spanend
- `0`:編集不可
-- `ListCellRenderer`で余白を指定
#spandel
combo00.setRenderer(lcr);
#spanend
#spandel
combo01.setRenderer(lcr);
#spanend
#spandel
combo02.setRenderer(lcr);
#spanend
----
#spandel
combo00.setEditable(false);
#spanend
#spandel
combo01.setEditable(true);
#spanend
#spandel
combo02.setEditable(true);
#spanend
- `1`: `JComboBox`が編集可 + テキストフィールドの元`Border` + 任意の`Border`で余白を設定
-- `editor.setBorder(BorderFactory.createCompoundBorder(editor.getBorder(), padding));`
-- `JComboBox#getEditor()#getEditorComponent()`で取得した`JTextField`に余白を指定
-- `JDK 1.5`では余白を指定しても反映されない
-- `JDK 1.6`では取得した`JTextFieldをsetOpaque(true)`としないと背景色は反映されない
#spandel
JTextField editor = (JTextField) combo01.getEditor().getEditorComponent();
#spanend
#spandel
editor.setBorder(padding);
#spanend
#spandel
editor.setOpaque(true);
#spanend
#spandel
editor.setBackground(new Color(.9f,1f,.9f));
#spanend
- `2`: `JComboBox`が編集可 + テキストフィールドの元`Border`は無視して任意の`Border`のみで余白を設定
-- `editor.setBorder(padding);`
-- `JComboBox#getEditor()#getEditorComponent()`で取得した`JTextField`に余白を指定
-- `MetalLookAndFeel`でテキストフィールドの枠が描画できない
#spandel
combo02.setBorder(BorderFactory.createCompoundBorder(combo02.getBorder(), padding));
#spanend
#spandel
//combo02.setOpaque(true);
#spanend
#spandel
//combo02.setBackground(new Color(.9f,1f,.9f));
#spanend
#spandel
- &jnlp;
- &jar;
- &zip;
- -
解説
JComboBoxが編集不可の場合、ListCellRendererで余白を指定することが出来ます。上記のサンプルでは、EmptyBorderの代わりにMatteBorderを使って余白を着色してテストしています。-
3
:JComboBox
が編集可 + テキストフィールドのInsets
+5
ピクセル余白を設定-
editor.setMargin(new Insets(i.top,i.left+5,i.bottom,i.right));
-
MetalLookAndFeel
、MotifLookAndFeel
、WindowsLookAndFeel
などでは無効 -
NimbusLookAndFeel
では有効だがJComboBox
の高さなども変化してしまう
-
- 上:編集不可
- ListCellRendererで余白を指定
-
4
:JComboBox
が編集可 + テキストフィールドのMargin
+5
ピクセル余白を設定-
editor.setMargin(new Insets(m.top,m.left+5,m.bottom,m.right));
-
MetalLookAndFeel
、MotifLookAndFeel
、WindowsLookAndFeel
などでは無効 -
NimbusLookAndFeel
では有効
-
- 中:編集可
- ListCellRendererで余白を指定
- JComboBox#getEditor()#getEditorComponent()で取得したJTextFieldに余白を指定
- JDK 1.5 では余白を指定しても反映されない
- JDK 1.6 では取得したJTextFieldをsetOpaque(true)としないと背景色は反映されない
- -
- 下:編集可
- ListCellRendererで余白を指定
- JComboBox#setBorder()で、元のBorderの内側に余白を指定
- JDK 1.6 では余計な?余白が発生する
-
5
:JComboBox
が編集可 +JComboBox
のBorder
+ 任意のBorder
で余白をJComboBox
自身に設定-
JComboBox#setBorder()
で元のBorder
の内側に余白を指定 -
WindowsLookAndFeel
、MotifLookAndFeel
で有効? -
MetalLookAndFeel
、NimbusLookAndFeel
ではJComboBox
の外側に余白が付く
-
-
6
:JComboBox
が編集可 +JComboBox
のBorder
+ 任意のBorder
で余白をJComboBox
自身に設定-
JComboBox#setBorder()
で元のBorder
の外側に余白を指定 -
WindowsLookAndFeel
で余計な枠が表示される?
-
以下のようにエディタにMarginを指定しても無視されるようです。
-
その他にも、以下のようにUIManager
で余白を設定する方法もあるがLookAndFeel
によって対応が異なる?ComboBox.padding
は無くなっている?-
JComboBox
が編集可能の場合はComboBox.editorBorder
が有効かもしれない#spandel editor = (JTextField) combo.getEditor().getEditorComponent(); #spanend #spandel Insets m = editor.getMargin(); #spanend #spandel Insets margin = new Insets(m.top,m.left+10,m.bottom,m.right); #spanend #spandel //System.out.println(margin.toString()); #spanend #spandel editor.setMargin(margin); #spanend #spanadd // UIManager.put("ComboBox.padding", new InsetsUIResource(insets)); #spanend #spanadd UIManager.put("ComboBox.editorBorder", BorderFactory.createEmptyBorder(0, 5, 0, 0)); #spanend
-
- 追記
- 無視されるのは、BasicLaF系(WindowsLaFなど)で、SynthLaF系(Nimbus, GTKなど)では上記の設定は有効になる?
- 1.6.0_10-beta-b13 では、BasicLaF系はUIManager.put("ComboBox.padding", insets) が使用できる?
-
上記のサンプルを余白に色無しにしてUbuntu 7.04
(GNOME 2.18.1
)、JDK 1.6.0
で実行すると、以下のように表示される
上記のサンプルを、余白に色無しにして、Ubuntu 7.04(GNOME 2.18.1) JDK 1.6.0 で実行すると、以下のよう*1になります。
#screenshot(,screenshot1.png)
-
LookAndFeel
毎にJComboBox
の余白の描画は異なるみたいなので、全部まとめて消すのは難しい? -
BasicComboBoxUI
も、ComboBox.buttonDarkShadow
がArrowButton
の三角とボタンの影に使われていて微妙-
BasicComboBoxUI#createArrowButton()
をオーバーライドして別途三角形アイコンを使う方がよさそう - コードは、JComboBoxのBorderを変更するに移動
-
参考リンク
参考リンク
- JComboBoxにアイコンを表示
- JDK-4515838 Can't change the border of a JComboBox - Java Bug System
- JDK-8179027 JComboBox too small under Windows LAF - Java Bug System
- 上記のスクリーンショットのような
WindowsLookAndFeel
でJComboBox
の高さが小さすぎる件が修正される?
- 上記のスクリーンショットのような
コメント
- なんだか、よく分からなくなってきましたorz。 -- terai
コメント
-
なんだか、よく分からなくなってきましたorz。JDK 1.6.0_10-beta-b22
で、BasicComboBoxUI
のpadding
にすこし修正が入っている?ようです。 -- aterai -
LookAndFeel
の切り替えなどを追加しました。 -- aterai -
1.7.0_06
でNimbus
などのComboBox.popupInsets
が修正? Bug ID: 7158712 Synth Property "ComboBox.popupInsets" is ignored -- aterai -
Windows 7
のLookAndFeel
、編集不可のJComboBox
で、((JLabel) combo.getRenderer() ).setBorder(padding);
がJComboBox
本体に効かない(フォーカスのためのBorder
のせい?)ため、セルレンダラーを作成して毎回余白を適用するように変更。このため、Windows 7
のLookAndFeel
では、JComboBox
本体の点線によるフォーカス表示が無くなる。 -- aterai