Swing: how to get container bind to JRadioButton?

微笑、不失礼 提交于 2019-12-24 18:06:13

问题


I have a bunch of dynamically added panels that contain radio button and a panel with several labels bind to radio button. Suppose I have a button that should retrieve container with labels bind to selected radio button or let's say another words - data bind to selected radio button. But how to get this container?

Here is my code where I try to do this (in fact this is a stub to show what is going on on UI (view) side):

public class Test extends JFrame {
    public static ButtonGroup radioButtons = new ButtonGroup();

    public Test() {
        super("Test");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(200, 300);

        final JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        JButton addButton = new JButton("Add");
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                panel.add(new PanelWithRadioButton("text1", "text2"));
                panel.revalidate();
            }
        });
        panel.add(addButton);

        JButton infoButton = new JButton("Info");
        infoButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for(Enumeration<AbstractButton> myRadioButtons = radioButtons.getElements();
                    myRadioButtons.hasMoreElements();) {
                    JRadioButton btn = (JRadioButton) myRadioButtons.nextElement();

                    if(btn.isSelected()) {
                        PanelWithTwoLabels panelWithLabels = (PanelWithTwoLabels) btn.getComponent(1); //Trying to get Component bind to selected JRadioButton
                        JOptionPane.showMessageDialog(null, "Text1: " + panelWithLabels.getLabel1Text() + ", Text2: " + panelWithLabels.getLabel2Text());
                    }
                }
            }
        });
        panel.add(infoButton);

        getContentPane().add(panel);
        setVisible(true);
    }

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

    //JRadioButton + Panel with two text fields
    private class PanelWithRadioButton extends JPanel {
        private JRadioButton rButton;
        private PanelWithTwoLabels panelWithTwoLabels;

        public PanelWithRadioButton(String text1, String text2) {
            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
            panelWithTwoLabels = new PanelWithTwoLabels(text1, text2);
            rButton = new JRadioButton();
            rButton.add(panelWithTwoLabels); //Bind Component to JRadioButton
            radioButtons.add(rButton);

            add(rButton);
            add(panelWithTwoLabels);
        }
    }

    private class PanelWithTwoLabels extends JPanel {
        private JLabel label1;
        private JLabel label2;

        public PanelWithTwoLabels(String text1, String text2) {
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            label1 = new JLabel(text1);
            label2 = new JLabel(text2);

            add(label1);
            add(label2);
        }

        private String getLabel1Text() {
            return label1.getText();
        }

        private String getLabel2Text() {
            return label2.getText();
        }
    }
}

回答1:


It sounds like you're working on a data driven Q&A program. While the approach shown is technically possible by recursively traversing the array returned from the container's getComponents() method, the result confuses the containment & inheritance hierarchies; it also scales poorly.

Instead, separate the model (strings, selection) and view (labels, buttons), as suggested here. Let the view listen to its model using one of the notification approaches shown. In this way, each instance of the view knows its own buttons and which button is selected. Almost any of the standard Swing components is a good example of this separable model architecture.

Addendum: While I'm reluctant to endorse the implicit design limitation, here's an expedient approach.

In PanelWithRadioButton, add a reference to panelWithTwoLabels as a client property:

rButton.putClientProperty("labels", panelWithTwoLabels);

In actionPerformed(), use the property to retrieve the panelWithTwoLabels:

PanelWithTwoLabels panelWithLabels =
    (PanelWithTwoLabels) btn.getClientProperty("labels");



回答2:


Not related to your question but...

panel.updateUI();

Don't use the updateUI() method that way. The updateUI() method is used internally by Swing when the LAF is changed.

When you add components to a visible GUI you should use:

panel.revalidat();
panel.repaint(); // sometimes needed


来源:https://stackoverflow.com/questions/18317679/swing-how-to-get-container-bind-to-jradiobutton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!