値とラベルをJComboBox
に設定して、ラベルを表示しても異なる値を取得することはできますか?
たとえば、JavaScriptでは次のことができます。
document.getElementById("myselect").options[0].value //accesses value attribute of 1st option
document.getElementById("myselect").options[0].text //accesses text of 1st option
JComboBox内に任意のオブジェクトを配置できます。デフォルトでは、オブジェクトのtoStringメソッドを使用して、キーボードを使用してコンボボックス内をナビゲートするラベルを表示します。したがって、最良の方法は、コンボ内で適切なオブジェクトを定義して使用することです。
public class ComboItem {
private String value;
private String label;
public ComboItem(String value, String label) {
this.value = value;
this.label = label;
}
public String getValue() {
return this.value;
}
public String getLabel() {
return this.label;
}
@Override
public String toString() {
return label;
}
}
コンボボックスでさまざまなラベルを簡単に使用できるようにするユーティリティインターフェイスとクラスを次に示します。置換ListCellRenderer
を作成する(そしてルックアンドフィールが変更された場合に見当違いになるリスクを冒す)代わりに、これはデフォルトのListCellRenderer
(それが何であれ)を使用しますが、値オブジェクトでtoString()
によって定義されたものではなく、ラベルテキストとしての独自の文字列。
public interface ToString {
public String toString(Object object);
}
public final class ToStringListCellRenderer implements ListCellRenderer {
private final ListCellRenderer originalRenderer;
private final ToString toString;
public ToStringListCellRenderer(final ListCellRenderer originalRenderer,
final ToString toString) {
this.originalRenderer = originalRenderer;
this.toString = toString;
}
public Component getListCellRendererComponent(final JList list,
final Object value, final int index, final boolean isSelected,
final boolean cellHasFocus) {
return originalRenderer.getListCellRendererComponent(list,
toString.toString(value), index, isSelected, cellHasFocus);
}
}
ご覧のとおり、ToStringListCellRenderer
はToString
実装からカスタム文字列を取得し、値オブジェクト自体を渡す代わりに、元のListCellRenderer
に渡します。
このコードを使用するには、次のようにします。
// Create your combo box as normal, passing in the array of values.
final JComboBox combo = new JComboBox(values);
final ToString toString = new ToString() {
public String toString(final Object object) {
final YourValue value = (YourValue) object;
// Of course you'd make your own label text below.
return "custom label text " + value.toString();
}
};
combo.setRenderer(new ToStringListCellRenderer(
combo.getRenderer(), toString)));
これを使用してカスタムラベルを作成するだけでなく、システムロケールに基づいて文字列を作成するToString
実装を作成すると、値オブジェクトを何も変更せずにコンボボックスを簡単に国際化できます。
完全な例を見せていただけますか?
Enum
のインスタンスは、これに特に便利です。 toString()
"宣言に含まれているように、この列挙型定数の名前を返します。"
import Java.awt.Color;
import Java.awt.Dimension;
import Java.awt.EventQueue;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** @see http://stackoverflow.com/questions/5661556 */
public class ColorCombo extends JPanel {
private Hue hue = Hue.values()[0];
public ColorCombo() {
this.setPreferredSize(new Dimension(320, 240));
this.setBackground(hue.getColor());
final JComboBox colorBox = new JComboBox();
for (Hue h : Hue.values()) {
colorBox.addItem(h);
}
colorBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Hue h = (Hue) colorBox.getSelectedItem();
ColorCombo.this.setBackground(h.getColor());
}
});
this.add(colorBox);
}
private enum Hue {
Cyan(Color.cyan), Magenta(Color.Magenta), Yellow(Color.yellow),
Red(Color.red), Green(Color.green), Blue(Color.blue);
private final Color color;
private Hue(Color color) {
this.color = color;
}
public Color getColor() {
return color;
}
}
private static void display() {
JFrame f = new JFrame("Color");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new ColorCombo());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
display();
}
});
}
}
ListCellRenderer を使用して、目的を達成します。 JLabel
を拡張し、ListCellRenderer
を実装するクラスを作成します。 setRenderer()
メソッドを使用して、そのクラスをJComboBox
のレンダラーとして設定します。これで、jcomboboxから値にアクセスすると、タイプはjlabelになります。
ステップ1たとえば、JComboBox
、id、nameの2つのプロパティを使用してクラスを作成します。
public class Product {
private int id;
private String name;
public Product(){
}
public Product(int id, String name){
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//this method return the value to show in the JComboBox
@Override
public String toString(){
return name;
}
}
ステップ2フォームのデザインで、JComboBox
を右クリックし、[プロパティ]を選択して、[コード]タブとプロパティを開きます。タイプパラメータはクラスの名前を書き込みます。この例ではProductです。
ステップ3ここで、クエリを使用してデータベースに接続し、製品のリストを生成するメソッドを作成します。このメソッドは、パラメーターとしてJComboBox
オブジェクト。
public void showProducts(JComboBox <Product> comboProduct){
ResultSet res = null;
try {
Connection conn = new Connection();
String query = "select id, name from products";
PreparedStatement ps = conn.getConecction().prepareStatement(query);
res = ps.executeQuery();
while (res.next()) {
comboProduct.addItem(new Product(res.getInt("id"), res.getString("name")));
}
res.close();
} catch (SQLException e) {
System.err.println("Error showing the products " + e.getMessage());
}
}
ステップ4フォームからメソッドを呼び出すことができます
public frm_products() {
initComponents();
Product product = new Product();
product.showProducts(this.cbo_product);
}
これで、getItemAt
メソッドを使用して選択したIDにアクセスできます
System.out.println(cbo_product.getItemAt(this.cbo_product.getSelectedIndex()).getId());