选择combobox上的项目时执行操作

我有一个包含item1和item2的jcombobox,我也有一个jtextfield ..当我在我的jcombobox上选择item1时我希望30出现在我的jtextfield上,而如果选择了Item2则为40 …我该怎么做?

这是你用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); } }); } } 

简单的解决方案是使用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; } } } 

不是原始问题的答案,而是在不破坏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的function(由自定义渲染器破坏)
  • 重用包装类(可以应用于任何数据类型)

与在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是一个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,用于查询渲染器的字符串表示

除字符串提供程序之外的所有内容都可以按原样重用(这正​​是自定义呈现器和keySelectionManager的一个实现)。 可以有字符串提供程序的一般实现,fi那些格式化值或通过reflection使用bean属性。 所有这些都没有违反基本规则:-)