问题
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