Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 选择组合框上的项目时执行操作_Java_Swing_Actionlistener_Jcombobox_Itemlistener - Fatal编程技术网

Java 选择组合框上的项目时执行操作

Java 选择组合框上的项目时执行操作,java,swing,actionlistener,jcombobox,itemlistener,Java,Swing,Actionlistener,Jcombobox,Itemlistener,我有一个包含item1和item2的jcombobox,还有一个jtextfield。。当我在jcombobox上选择item1时,我希望30显示在我的jtextfield上,而如果选择Item2,则显示40。。。如何做到这一点?简单的解决方案是使用itemstener。当状态更改时,您只需检查当前选定的项目并相应地设置文本 import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.ItemEv

我有一个包含item1和item2的jcombobox,还有一个jtextfield。。当我在jcombobox上选择item1时,我希望30显示在我的jtextfield上,而如果选择Item2,则显示40。。。如何做到这一点?

简单的解决方案是使用
itemstener
。当状态更改时,您只需检查当前选定的项目并相应地设置文本

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;
        }

    }

}
导入java.awt.BorderLayout;
导入java.awt.Component;
导入java.awt.EventQueue;
导入java.awt.event.ItemEvent;
导入java.awt.event.ItemListener;
导入javax.swing.DefaultListCellRenderer;
导入javax.swing.JComboBox;
导入javax.swing.JFrame;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类TestCombox06{
公共静态void main(字符串[]args){
新的testcombox06();
}
公共testcombox06(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私人JComboBox cb;
私有JTextField字段;
公共测试窗格(){
cb=新JComboBox(新项目[]{
新项目(“项目1”、“20”),
新项目(“项目2”、“30”);
cb.setRenderer(新的ItemCelLRenderer());
字段=新的JTextField(12);
添加(cb);
添加(字段);
cb.setSelectedItem(空);
cb.addItemListener(新的ItemListener(){
@凌驾
公共无效itemStateChanged(ItemEvent e){
Item=(Item)cb.getSelectedItem();
field.setText(item.getValue());
}
});
}
}
公共类项目{
私有字符串值;
私有字符串文本;
公共项(字符串文本、字符串值){
this.text=文本;
这个值=值;
}
公共字符串getText(){
返回文本;
}
公共字符串getValue(){
返回值;
}
}
公共类ItemCelLRenderer扩展了DefaultListCellRenderer{
@凌驾
公共组件getListCellRenderComponent(JList列表、对象值、int索引、布尔isSelected、布尔cellHasFocus){
super.getListCellRenderComponent(列表、值、索引、isSelected、cellHasFocus);//要更改生成的方法体,请选择工具|模板。
if(项的值实例){
setText(((项)值).getText());
}
归还这个;
}
}
}

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

这不是对原始问题的回答,而是如何在不破坏MVC的情况下创建可重用和可工作的自定义渲染器的示例:-)

在MVC环境中,这是错误的,因为它混合了数据和视图:现在模型不包含数据,而是包含一个包装器,该包装器是为了视图而引入的。这打破了关注点和封装的分离(与模型交互的每个类都需要知道包装的数据)

违反规则的驱动力是:

  • 保留默认KeySelectionManager的功能(该功能被自定义渲染器破坏)
  • 包装类的重用(可应用于任何数据类型)
正如在Swing中,自定义渲染器是设计用于容纳自定义视觉表现的小型硬币,无法处理的默认管理器是。。。破碎的调整设计以适应如此糟糕的默认设置是错误的,有点颠倒。正确的做法是实施应对管理

虽然重用是好的,但以破坏基本架构为代价进行重用并不是一个好的讨价还价

我们在表示域中遇到了一个问题,让我们在表示域中使用设计用于解决该问题的元素来解决它。正如您可能已经猜到的,已经有了这样的解决方案:-)

在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会查询呈现程序中的字符串repre
    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));
                  ....
             } 
         }
    
    }