2011-02-15 15 views
7

JComponents może uzyskać ukryte dane za pomocą setName() i getName(), prawda? Co z przedmiotami JComboBox? (Mam na myśli tych przedmiotów w JComboBox, a nie sam JComboBox)Java: Swing JComboBox, czy możliwe jest posiadanie ukrytych danych dla każdej pozycji na liście?

Co jeśli mam JComboBox, a wewnątrz niej mam listę nazw użytkowników (na przykład), teraz chcę mieć coś jak "id" dla każdej nazwy użytkownika na liście w zależności od tego, jak są zamawiane, jaki jest najlepszy sposób na zrobienie tego?

Odpowiedz

13
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.plaf.basic.*; 

public class ComboBoxItem extends JFrame implements ActionListener 
{ 
    public ComboBoxItem() 
    { 
     Vector model = new Vector(); 
     model.addElement(new Item(1, "car")); 
     model.addElement(new Item(2, "plane")); 
     model.addElement(new Item(3, "train")); 
     model.addElement(new Item(4, "boat")); 
     model.addElement(new Item(5, "boat aadf asfsdf a asd asd")); 

     JComboBox comboBox; 

     // Easiest approach is to just override toString() method 
     // of the Item class 

     comboBox = new JComboBox(model); 
     comboBox.addActionListener(this); 
     comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); 
     getContentPane().add(comboBox, BorderLayout.NORTH); 

     // Most flexible approach is to create a custom render 
     // to diplay the Item data 

     comboBox = new JComboBox(model); 
     comboBox.setRenderer(new ItemRenderer()); 
     comboBox.addActionListener(this); 
     getContentPane().add(comboBox, BorderLayout.SOUTH); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     JComboBox comboBox = (JComboBox)e.getSource(); 
     Item item = (Item)comboBox.getSelectedItem(); 
     System.out.println(item.getId() + " : " + item.getDescription()); 
    } 

    class ItemRenderer extends BasicComboBoxRenderer 
    { 
     public Component getListCellRendererComponent(
      JList list, Object value, int index, 
      boolean isSelected, boolean cellHasFocus) 
     { 
      super.getListCellRendererComponent(list, value, index, 
       isSelected, cellHasFocus); 

      if (value != null) 
      { 
       Item item = (Item)value; 
       setText(item.getDescription().toUpperCase()); 
      } 

      if (index == -1) 
      { 
       Item item = (Item)value; 
       setText("" + item.getId()); 
      } 


      return this; 
     } 
    } 

    class Item 
    { 
     private int id; 
     private String description; 

     public Item(int id, String description) 
     { 
      this.id = id; 
      this.description = description; 
     } 

     public int getId() 
     { 
      return id; 
     } 

     public String getDescription() 
     { 
      return description; 
     } 

     public String toString() 
     { 
      return description; 
     } 
    } 

    public static void main(String[] args) 
    { 
     JFrame frame = new ComboBoxItem(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

} 
+0

Dzięki za odpowiedź, naprawdę rozwiązać mój problem :) Ale ISN nie jest źle używać przestarzałego kodu "Wektor"? Czy istnieje sposób na uniknięcie używania wektory? – evilReiko

+1

Wektor nie jest przestarzały (przynajmniej w JDK6). Komponenty Swing używają modeli do przechowywania danych. DefaultComboBoxModel używa wektora do przechowywania danych. Jeśli ci się to nie podoba, zawsze możesz stworzyć własny model i użyć tego, co chcesz, aby przechowywać dane. – camickr

3

Tworzenie User klasę, która ma atrybuty username i id; zwraca tylko username w .toString().

+1

przesłonięcie toString ze względu na pokazywanie w JSomething to ** nie * zalecany sposób. Zobacz odpowiedź @camickr dla prawidłowego podejścia. – kleopatra

+1

to wcale nie jest w porządku (z wyjątkiem większości trywialnych aplikacji) - skończyłoby się na dziesiątkach wariantów Przedmiotów, które różnią się tylko ich implementacją toString tylko dlatego, że chcesz renderować je inaczej w różnych kontekstach. W Swing znajduje się mechanizm zaprojektowany do obsługi tej wariancji, a to renderer. – kleopatra

+0

nic wspólnego z robieniem czegoś z góry - po prostu robisz to źle w Swing-land ;-) Oczywiście możesz wierzyć inaczej. – kleopatra

4

Twój obiekt:

public class Item { 

    private int id; 
    private String name; 

    public Item(int id, String name) { 
     this.id = id; 
     this.name = name; 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String toString(){ 
     return this.name; 
    } 
} 

Dodaj elementy do JComboBox:

JComboBox combo; 

combo.addItem(new Item(1, "Test")); 
combo.addItem(new Item(15,"Test 2")); 

I dostać Item:

Item selected_item = (Item) combo.getSelectedItem(); 

System.out.println(selected_item.getId()); 
System.out.println(selected_item.getName()); 
+1

przesłonięcie toString ze względu na pokazywanie w JSomething to ** nie * zalecany sposób. Zobacz odpowiedź @camickr dla prawidłowego podejścia. – kleopatra

Powiązane problemy