JComboBoxのボタンやエディタ、ポップアップを変更する
以前、JComboBoxのポップアップの表示内容を変更する方法を考えてみました。JComboBoxでポップアップした選択肢の表示を変更する
http://symfoware.blog68.fc2.com/blog-entry-961.html
今回はもう一歩踏み込んで、ボタンも変更してみます。
最初のサンプル
普通のコンボボックスを表示するとこんな感じ。
- package sample;
- import java.awt.BorderLayout;
- import java.awt.Dimension;
- import java.awt.EventQueue;
- import javax.swing.JComboBox;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- public class Sample {
- public static void main(String[] args) {
- EventQueue.invokeLater(new Runnable() {
- @Override
- public void run() {
- startup();
- }
- });
- }
- private static void startup() {
- // 適当にコンボボックスを作成して配置する
- JComboBox combo = new JComboBox();
- combo.addItem("テスト1");
- combo.addItem("テスト2");
- JFrame frame = new JFrame();
- frame.setTitle("Java Version : " + System.getProperty("java.version"));
- frame.getContentPane().add(combo, BorderLayout.NORTH);
- frame.getContentPane().add(new JLabel("コンボボックスサンプル"), BorderLayout.CENTER);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setSize(new Dimension(350, 150));
- frame.setLocationRelativeTo(null);
- frame.setVisible(true);
- }
- }
コンボボックスのボタンを変更
色々調べてみたところ、ComboBoxUIを継承したクラスを作成すればよさそうです。
ボタンなどを変更できるか、JComboBoxを継承したMyComboBoxを作成。
UIにMetalComboBoxUIを継承したMyComboBoxUIを指定してやります。
- package sample;
- import java.awt.Color;
- import javax.swing.ComboBoxEditor;
- import javax.swing.JButton;
- import javax.swing.JCheckBox;
- import javax.swing.JComboBox;
- import javax.swing.JPanel;
- import javax.swing.JTextField;
- import javax.swing.ListCellRenderer;
- import javax.swing.plaf.ComboBoxUI;
- import javax.swing.plaf.basic.BasicComboBoxEditor;
- import javax.swing.plaf.basic.BasicComboBoxRenderer;
- import javax.swing.plaf.basic.BasicComboPopup;
- import javax.swing.plaf.basic.ComboPopup;
- import javax.swing.plaf.metal.MetalComboBoxUI;
- @SuppressWarnings("serial")
- public class MyComboBox extends JComboBox {
- // UIに自分が作ったMyComboBoxUIを設定する
- @Override
- public void setUI(ComboBoxUI ui) {
- super.setUI(new MyComboBoxUI());
- }
- // --- MetalComboBoxUIを継承して作成
- //BasicComboBoxUI, MetalComboBoxUI等が参考になります
- private class MyComboBoxUI extends MetalComboBoxUI {
- // editable = trueの時に使用されるテキストエディタを独自のものに置き換える
- protected ComboBoxEditor createEditor() {
- ComboBoxEditor editor = new MyComboBoxEditor();
- return editor;
- }
- // リストから選択されている項目を表示するときに使用されるレンダラーを
- // 独自の物に置き換える
- protected ListCellRenderer createRenderer() {
- return new MyComboBoxRenderer();
- }
- // ボタンを押した時に使用するポップアップメニューを変更
- protected ComboPopup createPopup() {
- BasicComboPopup popup = new BasicComboPopup(comboBox);
- popup.removeAll();
- // ポップアップの内容を書き換える
- JPanel panel = new JPanel();
- panel.add(new JCheckBox("チェックボックスに変えてみる"));
- popup.add(panel);
- return popup;
- }
- // コンボボックス右側に表示されるボタン
- protected JButton createArrowButton() {
- return new JButton("押");
- }
- }
- // --- リストから選択された項目を表示するときに使用するレンダラー
- private class MyComboBoxRenderer extends BasicComboBoxRenderer {
- // ちゃんと有効になっているか確認するため、何を選んでも同じ文字列を表示してみる
- @Override
- public String getText() {
- return "いつも同じ値";
- }
- }
- // --- editable = trueの時に使用されるエディタ
- private class MyComboBoxEditor extends BasicComboBoxEditor {
- @Override
- protected JTextField createEditorComponent() {
- JTextField editor = new JTextField();
- editor.setForeground(Color.red);
- editor.setBackground(Color.red);
- editor.setEditable(true);
- return editor;
- }
- }
- }
MyComboBoxを画面に表示してみます。
- package sample;
- import java.awt.BorderLayout;
- import java.awt.Dimension;
- import java.awt.EventQueue;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- public class Sample {
- public static void main(String[] args) {
- EventQueue.invokeLater(new Runnable() {
- @Override
- public void run() {
- startup();
- }
- });
- }
- private static void startup() {
- // 作成したMyComboBoxを表示する
- MyComboBox combo = new MyComboBox();
- combo.addItem("テスト1");
- combo.addItem("テスト2");
- JFrame frame = new JFrame();
- frame.setTitle("Java Version : " + System.getProperty("java.version"));
- frame.getContentPane().add(combo, BorderLayout.NORTH);
- frame.getContentPane().add(new JLabel("コンボボックスサンプル"), BorderLayout.CENTER);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setSize(new Dimension(350, 150));
- frame.setLocationRelativeTo(null);
- frame.setVisible(true);
- }
- }
狙い通りの表示になりました。
【参考URL】
http://terai.xrea.jp/Swing/_JComboBox.html
- 関連記事
-
- JavaFX 画面をFXMLで定義し、イベントを受け取る
- JavaFX を Ubuntu + Eclipseで使用する
- JComboBoxのボタンやエディタ、ポップアップを変更する
- JavaでDOMを使用してXMLを出力する時、アトリビュートの出力順を変更する
- launch4jで、Javaプログラム(.jar)をexeファイルでラップする
コメント
JComboBox
JComboBoxの調査をしていて、このブログにたどり着きました・・。
質問なのですが、JComboBoxでドロップダウンリスト(ポップアップメニュー)を表示させた状態で、
となりに配置してあるJTextFieldにマウスクリックでフォーカス移動してようとしても、
ドロップダウンリスト(ポップアップメニュー)が閉じるだけで、フォーカス移動してくれません。
Java1.5環境では、ドロップダウンリスト(ポップアップメニュー)が閉じ、フォーカス移動も行なわれてました。
Java7でも同様な動きにしたいと思っているのですが、対処方法等ご存知でしょうか?
よろしくお願い致します。
2014/10/01 19:27 by - URL 編集
Re: JComboBox
お役に立てず、すみません。
2014/10/05 17:57 by symfo URL 編集