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

标签 java swing jcombobox itemlistener

您好,Guru,我是一名初学者 Java swing 开发人员,正在尝试构建一个简单的应用程序...这是一个简化版本。

设置:1 个 JFrame、2 个基于 BorderLayout 的选项卡式面板(A 和 B),每个面板都有 1 个文本文件、共享 JPanel 类,其中组合框和 ItemListener 在每个选项卡的(北)中初始化

问题:如何根据文本字段来自哪个面板来控制文本字段文本的更新,例如。如果我在 TabA 中选择 Apples,项目监听器也会更新 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);    
    }    
}

最佳答案

由于您已经为每个选项卡创建了一个新的 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);

    }

}

更新了“模型”示例

这是一个非常基本的示例,只是模型的一种可能用途,用于桥接公共(public)面板和其他面板之间的更改。这意味着公共(public)面板不关心任何其他事情并更新提供的模型,这会向感兴趣的各方触发事件,他们可以根据需要采取适当的操作。

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;

        }

    }

}

关于java - 根据调用的选项卡更新组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17825432/

相关文章:

java - 如果文件在 Assets 目录下,如何将文件名作为字符串获取?

java - 创建 JTextField 来接收用户的输入

java - Repaint() 只工作了一半

java - JComboBox 的自定义字体

java - Windows 和 Linux 之间的 ActionListener 差异

java - 通过多个可选参数过滤 JPA 存储库

java - 无法使用录制的 mp3 作为 google 语音转文本 api 的输入..!

java - 在 Jboss 模块和项目依赖项之间选择库版本

java - 如何在类(class)中单独更新外观和感觉干净?

java - 组合框箭头按钮根据 nimbus LaF 中的字体大小进行拉伸(stretch)