2013-03-02 86 views
3

我有一個jcombobox包含item1和item2,我也有一個jtextfield ..當我選擇我的jcombobox的item1我想30出現在我的jtextfield而40如果Item2是選擇...我該怎麼做?當選擇組合框上的項目時執行動作

+0

http://stackoverflow.com/questions/8653901/jcombobox-actionperformed-event – Azodious 2013-03-02 10:24:04

回答

11

你這是怎麼用的ActionListener

import java.awt.FlowLayout; 
import java.awt.event.*; 

import javax.swing.*; 

public class MyWind extends JFrame{ 

    public MyWind() { 
     initialize(); 
    } 

    private void initialize() { 
     setSize(300, 300); 
     setLayout(new FlowLayout(FlowLayout.LEFT)); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final JTextField field = new JTextField(); 
     field.setSize(200, 50); 
     field.setText("    "); 

     JComboBox comboBox = new JComboBox(); 
     comboBox.setEditable(true); 
     comboBox.addItem("item1"); 
     comboBox.addItem("item2"); 

     // 
     // Create an ActionListener for the JComboBox component. 
     // 
     comboBox.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent event) { 
       // 
       // Get the source of the component, which is our combo 
       // box. 
       // 
       JComboBox comboBox = (JComboBox) event.getSource(); 

       Object selected = comboBox.getSelectedItem(); 
       if(selected.toString().equals("item1")) 
       field.setText("30"); 
       else if(selected.toString().equals("item2")) 
        field.setText("40"); 

      } 
     }); 
     getContentPane().add(comboBox); 
     getContentPane().add(field); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new MyWind().setVisible(true); 
      } 
     }); 
    } 
} 
+2

我喜歡你的答案,一個非常小的nit選擇,我可能會建議你做「項目1」.equals(選擇),而不是 - 雖然極不可能,它將防止可能的NullPointerExceptions;) – MadProgrammer 2013-03-02 10:54:20

2

簡單的解決方案是使用ItemListener。當狀態發生變化,則只需檢查當前選擇的項目和設置文本相應

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestComboBox06 { 

    public static void main(String[] args) { 
     new TestComboBox06(); 
    } 

    public TestComboBox06() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 

     }); 
    } 

    public class TestPane extends JPanel { 

     private JComboBox cb; 
     private JTextField field; 

     public TestPane() { 
      cb = new JComboBox(new String[]{"Item 1", "Item 2"}); 
      field = new JTextField(12); 

      add(cb); 
      add(field); 

      cb.setSelectedItem(null); 

      cb.addItemListener(new ItemListener() { 
       @Override 
       public void itemStateChanged(ItemEvent e) { 
        Object item = cb.getSelectedItem(); 
        if ("Item 1".equals(item)) { 
         field.setText("20"); 
        } else if ("Item 2".equals(item)) { 
         field.setText("30"); 
        } 
       } 
      }); 
     } 

    } 

} 

更好的解決方案是創建一個表示要顯示的值和與之關聯的值的自定義對象.. 。

更新

現在我不再有我的腳踝10個月咀嚼,我更新的例子使用ListCellRenderer這是一個更正確的做法,然後一直懶的和壓倒一切toString

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.event.ItemEvent; 
import java.awt.event.ItemListener; 
import javax.swing.DefaultListCellRenderer; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class TestComboBox06 { 

    public static void main(String[] args) { 
     new TestComboBox06(); 
    } 

    public TestComboBox06() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 

     }); 
    } 

    public class TestPane extends JPanel { 

     private JComboBox cb; 
     private JTextField field; 

     public TestPane() { 
      cb = new JComboBox(new Item[]{ 
       new Item("Item 1", "20"), 
       new Item("Item 2", "30")}); 
      cb.setRenderer(new ItemCelLRenderer()); 
      field = new JTextField(12); 

      add(cb); 
      add(field); 

      cb.setSelectedItem(null); 

      cb.addItemListener(new ItemListener() { 
       @Override 
       public void itemStateChanged(ItemEvent e) { 
        Item item = (Item)cb.getSelectedItem(); 
        field.setText(item.getValue()); 
       } 
      }); 
     } 

    } 

    public class Item { 
     private String value; 
     private String text; 

     public Item(String text, String value) { 
      this.text = text; 
      this.value = value; 
     } 

     public String getText() { 
      return text; 
     } 

     public String getValue() { 
      return value; 
     } 

    } 

    public class ItemCelLRenderer extends DefaultListCellRenderer { 

     @Override 
     public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 
      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //To change body of generated methods, choose Tools | Templates. 
      if (value instanceof Item) { 
       setText(((Item)value).getText()); 
      } 
      return this; 
     } 

    } 

} 
+0

非常感謝你〜用重寫的ToString(而不是一個適當的渲染器) – mitche027 2013-03-02 10:57:47

+0

包裝對象是_evil_ - 在這裏它可能看起來像是中間合理的,因爲您似乎需要另一個財產來支持其他財產......這是一個本土化的問題,因爲業務對象的保理是錯誤的,首先是:項目本身可能是業務對象,它的toString被一個完整的描述覆蓋,而不是與某個特定視圖相關的東西;-) – kleopatra 2013-03-02 14:22:06

+1

@kleopatra我完全同意,這是一個快速減少,因爲實際編碼的時間有限(沒有任何藉口),壞我 – MadProgrammer 2013-03-02 19:49:18

1

不是答案原來的問題,而是一個例子,該怎麼對做重複使用和工作自定義渲染做到不破壞MVC: - )

// WRONG 
public class DataWrapper { 
    final Data data; 
    final String description; 
    public DataWrapper(Object data, String description) { 
     this.data = data; 
     this.description = description; 
    } 
    .... 
    @Override 
    public String toString() { 
     return description; 
    } 
} 
// usage 
myModel.add(new DataWrapper(data1, data1.getName()); 

它是在一個MVC環境錯誤,因爲它是混合的數據和觀點:現在的模式不包含數據而是一個包裝,它是爲查看原因而引入的。這破壞了關注點和封裝的分離(每個與模型交互的類都需要知道包裝數據)。

的驅動力的規則斷裂是:

默認KeySelectionManager(其由一個定製渲染器斷開)的
  • 保持功能性的包裝類的
  • 重用(可以應用於任何數據類型)

由於在Swing定製呈現爲小硬幣的設計,以適應自定義可視化表示,這是無法應付是一個默認的經理......壞了。調整設計只是爲了適應這種糟糕的默認設置是錯誤的方式,倒過來。正確的是,實施應對經理。

雖然重複使用是好的,但以打破基本架構的代價這樣做並不是一個好的選擇。

我們在演示領域存在一個問題,讓我們在演示領域解決它,其中的元素旨在解決這個問題。正如你可能已經猜到了,SwingX已經:-)

這樣的解決方案在SwingX,一個字符串表示的提供程序被調用的StringValue,和所有默認渲染採取這樣的的StringValue自我配置:

StringValue sv = new StringValue() { 
    @Override 
    public String getString(Object value) { 
     if (value instanceof Data) { 
      return ((Data) value).getSomeProperty(); 
     } 
     return TO_STRING.getString(value); 
    } 
}; 
DefaultListRenderer renderer = new DefaultListRenderer(sv); 

由於defaultRenderer是-A的StringValue(實施委託給定的),KeySelectionManager的乖巧實現現在可以委託給渲染找到合適的項目:

public BetterKeySelectionManager implements KeySelectionManager { 

    @Override 
    public int selectionForKey(char ch, ComboBoxModel model) { 

     .... 
     if (getCellRenderer() instance of StringValue) { 
       String text = ((StringValue) getCellRenderer()).getString(model.getElementAt(row)); 
       .... 
     } 
    } 

} 

列出的一個接近角,因爲它是即使不使用SwingX容易實現,只需定義實現類似的東西,並用它:

  • 字符串表示
  • 自定義渲染器,是由供應商,保證在使用它配置的一些供應商配置本身
  • 乖巧keySelectionManager與查詢渲染器的字符串表示形式

之外的所有字符串提供可重複使用的,是(位於自定義渲染器和日恰好一個實行e keySelectionManager)。可以有字符串提供者的通用實現,f.i.這些格式化值或通過反射使用bean屬性。而且完全不會破壞基本規則:-)

+0

昨晚我真的找到一個帖子,你給出了同樣的例子。我當時不明白,現在也不明白。有時候我需要一個具體的例子,在它陷入之前。在我看來,你似乎只是創建另一個花哨的包裝類,調用getString()方法而不是toString()方法。你將如何使用MadProgrammer的Item類和StringValue類將項添加到ComboBoxModel?此外,由於只有渲染器知道文本,所以如何按排序順序添加ietms。你的StringValue類是否實現了Comparable? – camickr 2013-03-03 19:35:08

+0

價值/描述對有很多用途。例如一個產品。 「1」是一個錘子(打在我頭上),「2」是一個螺絲刀。某處你需要保持價值/描述的映射。所以說一個對象不能把這兩個屬性放在一起對我來說沒有任何意義。現在,這兩個屬性在一個類中可以通過使用適當的渲染器來選擇要在組合框中顯示哪些屬性。 – camickr 2013-03-04 00:34:40

+0

此外,您的產品可能會有多種不同語言的說明。因此,當您填充Item類時,您將直接從數據庫或資源文件或任何您使用的內容填充適當的描述。 – camickr 2013-03-04 00:41:33