I have a class named ControlsPanel. If I press a JButton (Start) in this class, the value of a boolean (isPressed) changes to true. In another class (CashRegistersPanel) I want
Your issue can be boiled down to simply this: how can one class be notified of a change of state in another class, when the change occurs. This is a common problem in event-driven GUI programs (and other program types as well) and is the whole reason that the observer or listener type design patterns were developed. So my suggestion is just that, that you somehow use a listener design pattern. This can be achieved in several ways including:
So a model class could look something like:
class Model {
public static final String START = "start"; // for the property change name
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
private boolean start = false;
public boolean isStart() {
return start;
}
public void setStart(boolean start) {
// to set up our PropertyChangeEvent
boolean oldValue = this.start;
boolean newValue = start;
this.start = start;
// notify our listeners that the start property has changed
pcSupport.firePropertyChange(START, oldValue, newValue);
}
// allow listeners to be added and removed
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
Edit For example, here is a M-V or Model-View simple example program:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class VerySimpleModelEg {
private static void createAndShowGui() {
Model model = new Model();
ButtonView view1 = new ButtonView();
DrawingView view2 = new DrawingView();
view1.setModel(model);
view2.setModel(model);
JPanel mainPanel = new JPanel(new GridLayout(1, 0));
mainPanel.add(view1);
mainPanel.add(view2);
JFrame frame = new JFrame("Very Simple Model Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Model {
public static final String START = "start"; // for the property change name
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(
this);
private boolean start = false;
public boolean isStart() {
return start;
}
public void setStart(boolean start) {
// to set up our PropertyChangeEvent
boolean oldValue = this.start;
boolean newValue = start;
this.start = start;
// notify our listeners that the start property has changed
pcSupport.firePropertyChange(START, oldValue, newValue);
}
// allow listeners to be added and removed
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
}
@SuppressWarnings("serial")
class ButtonView extends JPanel {
public static final String PRESS_TO_START = "Press To Start";
public static final String PRESS_TO_STOP = "Press To Stop";
private Model model;
private Action buttonAction = new ButtonAction();
public ButtonView() {
add(new JButton(buttonAction));
setBorder(BorderFactory.createTitledBorder("Button View"));
}
public void setModel(Model model) {
this.model = model;
model.addPropertyChangeListener(new BtnViewModelListener());
}
private class ButtonAction extends AbstractAction {
public ButtonAction() {
super(PRESS_TO_START);
}
@Override
public void actionPerformed(ActionEvent e) {
// if the button is pressed, toggle the state
// of the model's start property
model.setStart(!model.isStart());
}
}
private class BtnViewModelListener implements PropertyChangeListener {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
// if the model's start property changes
if (Model.START.equals(evt.getPropertyName())) {
// change the Action's name property
// which will change the JButton's text too!
String text = model.isStart() ? PRESS_TO_STOP : PRESS_TO_START;
buttonAction.putValue(Action.NAME, text);
}
};
}
}
@SuppressWarnings("serial")
class DrawingView extends JPanel {
private static final Color START_COLOR = Color.red;
private static final Color STOP_COLOR = Color.blue;
private Model model;
public DrawingView() {
setBorder(BorderFactory.createTitledBorder("Drawing View"));
setBackground(STOP_COLOR);
}
public void setModel(Model model) {
this.model = model;
model.addPropertyChangeListener(new DrawingViewModelListener());
}
private class DrawingViewModelListener implements PropertyChangeListener {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
// if the model's start property changes
if (Model.START.equals(evt.getPropertyName())) {
// change the color of the JPanel
Color bg = model.isStart() ? START_COLOR : STOP_COLOR;
setBackground(bg);
}
};
}
}
And yes, this may be a bit of over-kill for your very simple situation, but it scales up nicely since you can with this separate the model and the GUI concerns.