Swing/PaddingComboBox のバックアップの現在との差分(No.14)
TITLE:JComboBoxの内余白
Posted by aterai at 2007-05-28
JComboBoxの内余白
JComboBoxのエディタなどに内余白を設定します。- category: swing folder: PaddingComboBox title: JComboBoxの内余白 tags: [JComboBox, Border, LookAndFeel, JTextField] author: aterai pubdate: 2007-05-28T05:42:18+09:00 description: JComboBoxのエディタなどに内余白を設定します。 image:
概要
JComboBox
のエディタなどに内余白を設定します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#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
**サンプルコード [#o79d2c4d]
#spanend
#spandel
#code{{
#spanend
#spandel
Border padding = BorderFactory.createEmptyBorder(0,5,0,0);
#spanend
#spandel
ListCellRenderer lcr = combo.getRenderer();
#spanend
#spandel
((JLabel)lcr).setBorder(padding);
#spanend
#spandel
combo.setRenderer(lcr);
#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
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JComboBox に、Border*1を設定したListCellRendererを設定して、ドロップダウンリストの左余白をすこし広げています。 JComboBoxが編集不可の場合、エディタ部分もこの余白が自動的に適用されます。解説
上記のサンプルでは、JComboBox
にBorder
(EmptyBorder
とMatteBorder
を切り替え可能)を設定したListCellRenderer
を設定して、ドロップダウンリストの左余白をすこし広げています。JComboBox
が編集不可の場合、エディタ部分もこの余白が自動的に適用されます。
- 0:編集不可
- ListCellRendererで余白を指定
-
0
:編集不可-
ListCellRenderer
で余白を指定
-
以下は、JComboBoxが編集可の場合のテストです。
- 1: テキストフィールドの元Border + 任意のBorderで余白を設定
- editor.setBorder(BorderFactory.createCompoundBorder(editor.getBorder(), padding));
- JComboBox#getEditor()#getEditorComponent()で取得したJTextFieldに余白を指定
- JDK 1.5 では余白を指定しても反映されない
- JDK 1.6 では取得したJTextFieldをsetOpaque(true)としないと背景色は反映されない
-
1
:JComboBox
が編集可 + テキストフィールドの元Border
+ 任意のBorder
で余白を設定-
editor.setBorder(BorderFactory.createCompoundBorder(editor.getBorder(), padding));
-
JComboBox#getEditor()#getEditorComponent()
で取得したJTextField
に余白を指定 -
JDK 1.5
では余白を指定しても反映されない -
JDK 1.6
では取得したJTextFieldをsetOpaque(true)
としないと背景色は反映されない
-
- 2: テキストフィールドの元Borderは無視して任意のBorderのみで余白を設定
- editor.setBorder(padding);
- JComboBox#getEditor()#getEditorComponent()で取得したJTextFieldに余白を指定
- Metal L&F でテキストフィールドの枠が描画できない
-
2
:JComboBox
が編集可 + テキストフィールドの元Border
は無視して任意のBorder
のみで余白を設定-
editor.setBorder(padding);
-
JComboBox#getEditor()#getEditorComponent()
で取得したJTextField
に余白を指定 -
MetalLookAndFeel
でテキストフィールドの枠が描画できない
-
- 3: テキストフィールドのInsets + 5ピクセル余白を設定
- editor.setMargin(new Insets(i.top,i.left+5,i.bottom,i.right));
- Metal, Motif, Windows L&F などでは無効
- Nimbus L&F では有効だが、JComboBoxの高さなども変化してしまう
-
3
:JComboBox
が編集可 + テキストフィールドのInsets
+5
ピクセル余白を設定-
editor.setMargin(new Insets(i.top,i.left+5,i.bottom,i.right));
-
MetalLookAndFeel
、MotifLookAndFeel
、WindowsLookAndFeel
などでは無効 -
NimbusLookAndFeel
では有効だがJComboBox
の高さなども変化してしまう
-
- 4: テキストフィールドのMargin + 5ピクセル余白を設定
- editor.setMargin(new Insets(m.top,m.left+5,m.bottom,m.right));
- Metal, Motif, Windows L&F などでは無効
- Nimbus L&F では有効
-
4
:JComboBox
が編集可 + テキストフィールドのMargin
+5
ピクセル余白を設定-
editor.setMargin(new Insets(m.top,m.left+5,m.bottom,m.right));
-
MetalLookAndFeel
、MotifLookAndFeel
、WindowsLookAndFeel
などでは無効 -
NimbusLookAndFeel
では有効
-
- 5: JComboBoxのBorder + 任意のBorderで余白をJComboBox自身に設定
- JComboBox#setBorder()で、元のBorderの内側に余白を指定
- Windows, Motif L&F で有効?
- Metal, Nimbus L&F では、JComboBoxの外側に余白が付く
-
5
:JComboBox
が編集可 +JComboBox
のBorder
+ 任意のBorder
で余白をJComboBox
自身に設定-
JComboBox#setBorder()
で元のBorder
の内側に余白を指定 -
WindowsLookAndFeel
、MotifLookAndFeel
で有効? -
MetalLookAndFeel
、NimbusLookAndFeel
ではJComboBox
の外側に余白が付く
-
- 6: JComboBoxのBorder + 任意のBorderで余白をJComboBox自身に設定
- JComboBox#setBorder()で、元のBorderの外側に余白を指定
- Windows L&F で余計な枠が表示される?
-
6
:JComboBox
が編集可 +JComboBox
のBorder
+ 任意のBorder
で余白をJComboBox
自身に設定-
JComboBox#setBorder()
で元のBorder
の外側に余白を指定 -
WindowsLookAndFeel
で余計な枠が表示される?
-
その他にも、以下のように余白を設定する方法もありますが、L&F によって対応が異なるようです。
-
その他にも、以下のようにUIManager
で余白を設定する方法もあるがLookAndFeel
によって対応が異なる?ComboBox.padding
は無くなっている?-
JComboBox
が編集可能の場合はComboBox.editorBorder
が有効かもしれない#spandel UIManager.put("ComboBox.padding", new InsetsUIResource(insets)); #spanend #spanadd // UIManager.put("ComboBox.padding", new InsetsUIResource(insets)); #spanend #spanadd UIManager.put("ComboBox.editorBorder", BorderFactory.createEmptyBorder(0, 5, 0, 0)); #spanend
-
- - 上記のサンプルを、余白に色無しにして、Ubuntu 7.04(GNOME 2.18.1) JDK 1.6.0 で実行すると、以下のようになります。
-
上記のサンプルを余白に色無しにしてUbuntu 7.04
(GNOME 2.18.1
)、JDK 1.6.0
で実行すると、以下のように表示される
- Look&Feel毎にJComboBoxの余白の描画は異なるみたいなので、全部まとめて消すのは難しい?
- BasicComboBoxUI も、ComboBox.buttonDarkShadow がArrowButtonの三角とボタンの影に使われていて微妙
- BasicComboBoxUI#createArrowButton()をオーバーライドして別途三角形アイコンを使う方がよさそう
#spanend #spandel import java.awt.*; #spanend #spandel import javax.swing.*; #spanend #spandel import javax.swing.plaf.basic.*; #spanend #spandel public class ComboBoxInsetsTest { #spanend public JComponent makeUI() { UIManager.put("ComboBox.foreground", Color.WHITE); UIManager.put("ComboBox.background", Color.BLACK); UIManager.put("ComboBox.selectionForeground", Color.CYAN); UIManager.put("ComboBox.selectionBackground", Color.BLACK); - `LookAndFeel`毎に`JComboBox`の余白の描画は異なるみたいなので、全部まとめて消すのは難しい? - `BasicComboBoxUI`も、`ComboBox.buttonDarkShadow`が`ArrowButton`の三角とボタンの影に使われていて微妙 -- `BasicComboBoxUI#createArrowButton()`をオーバーライドして別途三角形アイコンを使う方がよさそう -- コードは、[[JComboBoxのBorderを変更する>Swing/ComboBoxBorder]]に移動 UIManager.put("ComboBox.buttonDarkShadow", Color.BLACK); UIManager.put("ComboBox.buttonBackground", Color.WHITE); UIManager.put("ComboBox.buttonHighlight", Color.WHITE); UIManager.put("ComboBox.buttonShadow", Color.WHITE); #spanadd * 参考リンク [#reference] #spanend - [[JComboBoxにアイコンを表示>Swing/IconComboBox]] - [https://bugs.openjdk.org/browse/JDK-4515838 JDK-4515838 Can't change the border of a JComboBox - Java Bug System] - [https://bugs.openjdk.org/browse/JDK-8179027 JDK-8179027 JComboBox too small under Windows LAF - Java Bug System] -- 上記のスクリーンショットのような`WindowsLookAndFeel`で`JComboBox`の高さが小さすぎる件が修正される? UIManager.put("ComboBox.border", BorderFactory.createLineBorder(Color.WHITE)); UIManager.put("ComboBox.editorBorder", BorderFactory.createLineBorder(Color.GREEN)); #spanadd * コメント [#comment] #spanend #spanadd #comment #spanend - %%なんだか、よく分からなくなってきましたorz。%% `JDK 1.6.0_10-beta-b22`で、`BasicComboBoxUI`の`padding`にすこし修正が入っている?ようです。 -- &user(aterai); &new{2008-03-11 (火) 21:38:58}; - `LookAndFeel`の切り替えなどを追加しました。 -- &user(aterai); &new{2008-04-02 (水) 20:08:01}; - `1.7.0_06`で`Nimbus`などの`ComboBox.popupInsets`が修正? [https://bugs.openjdk.org/browse/JDK-7158712 Bug ID: 7158712 Synth Property "ComboBox.popupInsets" is ignored] -- &user(aterai); &new{2012-08-15 (水) 13:58:34}; - `Windows 7`の`LookAndFeel`、編集不可の`JComboBox`で、`((JLabel) combo.getRenderer() ).setBorder(padding);`が`JComboBox`本体に効かない(フォーカスのための`Border`のせい?)ため、セルレンダラーを作成して毎回余白を適用するように変更。このため、`Windows 7`の`LookAndFeel`では、`JComboBox`本体の点線によるフォーカス表示が無くなる。 -- &user(aterai); &new{2013-11-19 (火) 15:37:19}; DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(); model.addElement("aaaa"); model.addElement("aaaabbb"); model.addElement("aaaabbbcc"); model.addElement("1234123512351234"); model.addElement("bbb1"); model.addElement("bbb12"); JComboBox<String> combo = new JComboBox<>(model); combo.setUI(new BasicComboBoxUI()); #spandel #spanend Object o = combo.getAccessibleContext().getAccessibleChild(0); ((JComponent)o).setBorder(BorderFactory.createMatteBorder(0,1,1,1,Color.WHITE)); #spandel #spanend JPanel p = new JPanel(); p.setOpaque(true); p.setBackground(Color.BLACK); p.add(combo); return p; } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } public static void createAndShowGUI() { JFrame f = new JFrame(); f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); f.getContentPane().add(new ComboBoxInsetsTest().makeUI()); f.setSize(320, 240); f.setLocationRelativeTo(null); f.setVisible(true); } #spandel } #spanend #spandel
- BasicComboBoxUI#createArrowButton()をオーバーライドして別途三角形アイコンを使う方がよさそう