Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I think that key is to use an <strong><a href="http://www.javaworld.com/javaworld/javaqa/2001-05/04-qa-0525-observer.html" rel="nofollow noreferrer">Observer Design Pattern</a></strong> to allow one object to listen for changes in state in another object.</p> <p>I assume that each Player class has a health field. I would make this a "bound" property by giving the Player class a private SwingPropertyChangeSupport field, by giving the Player class <code>addPropertyChangeListener</code> and <code>removePropertyChangeListener</code> methods, and by notifying your listeners of health changes by calling <code>firePropertyChange(...)</code> method whenever the health property is changed inside of its <code>setHealth(...)</code> method. This way any class that needs to listen for changes to health (or any other bound property of the Player class) can do so and can respond to these changes as need be. This is another reason why class fields/properties should be private and only changed via setter methods.</p> <p>For example:</p> <h2>Driver class, PropChangeEg.java</h2> <pre><code>import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.*; import javax.swing.event.*; public class PropChangeEg { private static void createAndShowGui() { JFrame frame = new JFrame("Prop Change Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new PlayerPanel(new Player("Pete"))); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } </code></pre> <h2>Player.java class</h2> <pre><code>class Player { public static final String HEALTH = "health"; private SwingPropertyChangeSupport propChangeSupport = new SwingPropertyChangeSupport(this); private String name; private int health = 100; public Player(String name) { this.name = name; } public void addPropertyChangeListener(PropertyChangeListener listener) { propChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propChangeSupport.removePropertyChangeListener(listener); } public int getHealth() { return health; } public void setHealth(int health) { int oldValue = this.health; int newValue = health; this.health = health; propChangeSupport.firePropertyChange(HEALTH, oldValue, newValue); } public String getName() { return name; } } </code></pre> <h2>PlayerPanel.java class</h2> <pre><code>@SuppressWarnings("serial") class PlayerPanel extends JPanel { private Player player; private JButton fireButton = new JButton("Fire"); private JSlider healthSlider; public PlayerPanel(final Player player) { this.player = player; setBorder(BorderFactory.createTitledBorder("Player: " + player.getName())); healthSlider = new JSlider(0, 100, player.getHealth()); healthSlider.setBorder(BorderFactory.createTitledBorder("Health")); healthSlider.setPaintLabels(true); healthSlider.setPaintTicks(true); healthSlider.setPaintTicks(true); healthSlider.setMajorTickSpacing(20); healthSlider.setMinorTickSpacing(5); add(healthSlider); add(fireButton); healthSlider.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent evt) { player.setHealth(healthSlider.getValue()); } }); player.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(Player.HEALTH)) { fireButton.setEnabled(player.getHealth() &gt; 0); } } }); } public Player getPlayer() { return player; } } </code></pre> <p>This will result in a JButton that responds to the value held by the Player's health. For example, here are two screens from this GUI, one with a positive non-zero health value, and one where the health value of Player is zero:</p> <p><img src="https://i.stack.imgur.com/7XcNo.jpg" alt="enter image description here"></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload