根据调用的选项卡更新组件

时间:2013-07-24 04:50:05

标签: java swing jcombobox itemlistener

Hello Guru我是Java初学者,我正在尝试构建一个简单的应用程序...这里是一个简化版本。

设置:1个JFrame,2个基于BorderLayout的选项卡式面板(A和B)每个都有1个textfiled,共享的JPanel类,带有组合框,并且每个选项卡(North)中初始化了ItemListener

问题:如何根据文本字段来自哪个面板来控制文本字段文本的更新,例如。如果我在TabA中选择Apples,则Item Listener也会更新TabB上的TextField。我想要完成的是确定调用来自TabA或TabB的位置,并仅更新与该选项卡关联的文本字段。

希望这有一定意义

public class Main extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    public JTextField tfPanelA;
    public JTextField tfPanelB;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Main frame = new Main();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Main() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);            
        JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        contentPane.add(tabbedPane, BorderLayout.CENTER);           
        JPanel panelA = new JPanel();
        tabbedPane.addTab("Tab A", null, panelA, null);
        panelA.setLayout(new BorderLayout(0, 0));           
        sharedPanel s1 = new sharedPanel(this);
        panelA.add(s1, BorderLayout.NORTH);         
        tfPanelA = new JTextField();
        panelA.add(tfPanelA);
        tfPanelA.setColumns(10);            
        JPanel panelB = new JPanel();
        tabbedPane.addTab("Tab B", null, panelB, null);
        panelB.setLayout(new BorderLayout(0, 0));           
        sharedPanel s2 = new sharedPanel(this);
        panelB.add(s2, BorderLayout.NORTH);
        tfPanelB = new JTextField();
        panelB.add(tfPanelB);
        tfPanelB.setColumns(10);
    }    
}

//共享班级......

    public class sharedPanel extends JPanel {

    private Main app;
    private String[] clist = {"Apples","Oranges","Bananas"};
    /**
     * Create the panel.
     */
    public sharedPanel(final Main app) {
        this.app=app;
        setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));         
        JComboBox<String> comboBox = new JComboBox<String>();
        comboBox.setModel(new DefaultComboBoxModel<String>(clist));         
        comboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
             //update PanelA's textfield ONLY if called from PanelA
             // do this if called from PanelA
                app.tfPanelA.setText(e.getItem().toString());   
             // do this if called from PanelB
                app.tfPanelB.setText(e.getItem().toString());
            }
        });         
        add(comboBox);    
    }    
}

2 个答案:

答案 0 :(得分:1)

由于你有SharedPanel的两个实例,你可以添加要更新的文本字段作为对构造函数的引用:

SharedPanel s1 = new SharedPanel(this, tfPanelA);

public SharedPanel(final Main app, final JTextField tf) {
    ...
    comboBox.addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e) {
            tf.setText(e.getItem().toString());
        }
    });
    ...
}

答案 1 :(得分:1)

由于您为每个标签创建了sharedPanel的新实例,只需提供对要更新的文本字段的引用...

你最终会得到更像......

public class sharedPanel extends JPanel {

    private JTextField field;
    private String[] clist = {"Apples","Oranges","Bananas"};
    public sharedPanel(final JTextField field) {
        this.field=field;
        setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

        JComboBox<String> comboBox = new JComboBox<String>();
        comboBox.setModel(new DefaultComboBoxModel<String>(clist));

        comboBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                sharedPanel.this.field.setText(e.getItem().toString());   
            }
        });

        add(comboBox);

    }

}

更新了“模特”示例

这是一个非常基本的例子,可以使用模型来桥接公共面板和其他面板之间的变化。这意味着公共面板不关心任何其他内容并更新提供的模型,该模型会向可以根据需要采取适当措施的相关方发送事件。

enter image description here enter image description here

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TabbedModel {

    protected static final String[] MAIN_LIST = {"Apples","Oranges","Bananas"};

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

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

                JTabbedPane tabPane = new JTabbedPane();
                tabPane.addTab("A", new ATab());
                tabPane.addTab("B", new ATab());

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

    public class DefaultCommonModel implements CommonModel {

        private List<ChangeListener> listeners;
        private String value;

        public DefaultCommonModel() {
            listeners = new ArrayList<>(25);
        }

        @Override
        public void addChangeListener(ChangeListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeChangeListener(ChangeListener listener) {
            listeners.remove(listener);
        }

        @Override
        public void setValue(String aValue) {
            if (aValue == null ? value != null : !aValue.equals(value)) {
                value = aValue;
                fireStateChanged();
            }
        }

        @Override
        public String getValue() {
            return value;
        }

        protected void fireStateChanged() {

            if (!listeners.isEmpty()) {
                ChangeEvent evt = new ChangeEvent(this);
                for (ChangeListener listener : listeners) {
                    listener.stateChanged(evt);
                }
            }

        }

    }

    public interface CommonModel {

        public void addChangeListener(ChangeListener listener);
        public void removeChangeListener(ChangeListener listener);

        public void setValue(String value);
        public String getValue();

    }

    public class CommonPanel extends JPanel {

        private CommonModel model;
        private JComboBox comboBox;

        public CommonPanel(CommonModel model) {
            this.model = model;
            setLayout(new GridBagLayout());
            comboBox = new JComboBox(new DefaultComboBoxModel<>(MAIN_LIST));
            comboBox.addItemListener(new ItemListener() {
                @Override
                public void itemStateChanged(ItemEvent e) {
                    String value = (String) e.getItem();
                    CommonPanel.this.model.setValue(value);
                }
            });
            add(comboBox);
        }

    }

    public class ATab extends JPanel {

        private List<JTextField> fields;

        public ATab() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            DefaultCommonModel model = new DefaultCommonModel();
            model.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    CommonModel model = (CommonModel) e.getSource();
                    for (JTextField field : fields) {
                        field.setText(model.getValue());
                    }
                }
            });
            CommonPanel commonPanel = new CommonPanel(model);

            add(commonPanel, gbc);

            fields = new ArrayList<>(25);
            for (int index = 0; index < random(); index++) {
                JTextField field = new JTextField(10);
                add(field, gbc);
                fields.add(field);
            }
        }

        protected int random() {

            return (int)Math.round(Math.random() * 9) + 1;

        }

    }

}