我有一个包含item1和item2的jcombobox,我也有一个jtextfield ..当我在我的jcombobox上选择item1时我希望30出现在我的jtextfield上,而如果选择了Item2则为40 ...我该怎么办?< / p>
答案 0 :(得分: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);
}
});
}
}
答案 1 :(得分: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;
}
}
}
答案 2 :(得分: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环境中错误,因为它混合了数据和视图:现在模型不包含数据,而是为<引入的包装器em>查看原因。这打破了关注点和封装的分离(每个与模型交互的类都需要知道包装数据)。
违反规则的驱动力是:
在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的一个实现)。可以存在字符串提供者的一般实现,f.i。那些格式化值或通过反射使用bean属性。并且所有这些都没有违反基本规则: - )