• category: swing folder: SpinnerTextColor title: JComboBoxをJSpinnerの代わりに使用する tags: [JSpinner, JComboBox, ListCellRenderer, Html, ActionMap] author: aterai pubdate: 2013-04-29T08:31:48+09:00 description: JSpinnerの代わりにJComboBoxを使用することで、アイテムの文字色などを変更しています。 image: https://lh6.googleusercontent.com/-kpruQCgOnLE/UX2r6exfrII/AAAAAAAABqo/JZnFlTBy1zw/s800/SpinnerTextColor.png

概要

JSpinnerの代わりにJComboBoxを使用することで、アイテムの文字色などを変更しています。

サンプルコード

JButton nb = createArrowButton(SwingConstants.NORTH);
nb.addActionListener(new ActionListener() {
  @Override public void actionPerformed(ActionEvent e) {
    e.setSource(comboBox);
    comboBox.getActionMap().get("selectPrevious2").actionPerformed(e);
  }
});
JButton sb = createArrowButton(SwingConstants.SOUTH);
sb.addActionListener(new ActionListener() {
  @Override public void actionPerformed(ActionEvent e) {
    e.setSource(comboBox);
    comboBox.getActionMap().get("selectNext2").actionPerformed(e);
  }
});
Box box = Box.createVerticalBox();
box.add(nb);
box.add(sb);

JPanel p = new JPanel(new BorderLayout()) {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    return new Dimension(d.width, 20);
  }
};
p.add(comboBox);
p.add(box, BorderLayout.EAST);
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、ドロップダウンリストの表示を無効にしたJComboBox2つのArrowButtonを組み合わせて、JSpinner風のコンポーネントを作成しています。JComboBoxのセルレンダラーはHtmlタグが使用可能なので、各アイテムの文字色を<font>タグを使って変更しています。


  • 以下は、JSpinnerEditorJFormattedTextFieldからJLabelに変更する場合のサンプル
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.Objects;
import javax.swing.*;
import javax.swing.event.*;

public class SpinnerTest {
  public JComponent makeUI() {
    String[] items = {
      "<html><font color='red'>Sunday</font> <font color='gray'>(Sun.)",
      "<html><font color='black'>Monday</font> <font color='gray'>(Mon.)",
      "<html><font color='black'>Tuesday</font> <font color='gray'>(Tue.)",
      "<html><font color='black'>Wednesday</font> <font color='gray'>(Wed.)",
      "<html><font color='black'>Thursday</font> <font color='gray'>(Thu.)",
      "<html><font color='black'>Friday</font> <font color='gray'>(Fri.)",
      "<html><font color='blue'>Saturday</font> <font color='gray'>(Sat.)"
    };
    SpinnerListModel model = new SpinnerListModel(items);
    JSpinner spinner = new JSpinner(model) {
      @Override public void setEditor(JComponent editor) {
        JComponent oldEditor = getEditor();
        if (!editor.equals(oldEditor) && oldEditor instanceof HTMLListEditor) {
          ((HTMLListEditor) oldEditor).dismiss(this);
        }
        super.setEditor(editor);
      }
    };
    spinner.setEditor(new HTMLListEditor(spinner));

    JPanel p = new JPanel();
    p.add(spinner);
    return p;
  }

  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {
        e.printStackTrace();
      }
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new SpinnerTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class HTMLListEditor extends JLabel implements ChangeListener {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.width = 200;
    return d;
  }
  private final JSpinner spinner;

  protected HTMLListEditor(JSpinner spinner) {
    super();

    if (!(spinner.getModel() instanceof SpinnerListModel)) {
      throw new IllegalArgumentException("model not a SpinnerListModel");
    }
    this.spinner = spinner;
    spinner.addChangeListener(this);

    setText(Objects.toString(spinner.getValue()));
    setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
    setOpaque(true);
    setBackground(Color.WHITE);
    setInheritsPopupMenu(true);

    String toolTipText = spinner.getToolTipText();
    if (toolTipText != null) {
      setToolTipText(toolTipText);
    }
  }
  @Override public void stateChanged(ChangeEvent e) {
    JSpinner spinner = (JSpinner) e.getSource();
    setText(Objects.toString(spinner.getValue()));
  }
  public void dismiss(JSpinner spinner) {
    spinner.removeChangeListener(this);
  }
}

参考リンク

コメント