I would throw in some MVC it's a lot more work, but it makes for more flexible coding.
First a ModelBean
with a boolean checked
and propertyChangeSupport
for firing property change events
import java.beans.*;
import java.io.Serializable;
public class ModelBean implements Serializable {
private boolean checked;
private PropertyChangeSupport propertySupport;
public ModelBean() {
propertySupport = new PropertyChangeSupport(this);
}
public boolean getChecked() {
return checked;
}
public void setChecked(boolean checked) {
boolean oldValue = this.checked;
this.checked = checked;
propertySupport.firePropertyChange("checked", oldValue, this.checked);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertySupport.removePropertyChangeListener(listener);
}
}
Then you have your main GUI
class that takes the ModelBean
as an argument
class GUI extends JFrame {
private ModelBean model;
private JCheckBox cbox;
public GUI(ModelBean model) {
this.model = model;
cbox = new JCheckBox("Check and watch me print");
cbox.addItemListener(new CheckListener(model));
setLayout(new GridBagLayout());
add(cbox);
setSize(300, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
}
And you ItemListener
class that takes the same ModelBean
as an argument and also adds the PropertyChangeListener
to the model
class CheckListener implements ItemListener {
private ModelBean model;
public CheckListener(ModelBean newModel) {
this.model = newModel;
model.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
System.out.println(model.getChecked());
}
});
}
@Override
public void itemStateChanged(ItemEvent e) {
JCheckBox source = (JCheckBox) e.getSource();
if (source.isSelected()) {
model.setChecked(true);
} else {
model.setChecked(false);
}
}
}
Then you class to run the program
public class TestMVC {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final ModelBean model = new ModelBean();
GUI gui = new GUI(model);
}
});
}
}
It seems like a lot of work just for a silly boolean
but the concept is a better overall design for larger programs where a lot of different data needs to be manipulated and listened to for changes.
UPDATE
Another option, if your GUI is the parent container, and you don't want to expose it by passing it by reference, you can create an interface
and have GUI
implement it
public interface BooleanInterface {
public void setBoolean(boolean bool);
}
public class GUI extends JFrame implements BooleanInterface {
boolean bool;
@Override
public void setBoolean(boolean bool) {
this.bool = bool;
}
}
public BoxListener implements ActionListener {
BooleanInterface boolFace;
public BoxListener(BooleanInterface boolFace) {
this.boolFace = boolFace;
}
}
You can then pass the GUI
to the listener. Though it looks the same as what you're already doing, it actually isn't, since it no longer exposes the GUI
, instead uses the interface.