import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; /** * Abstract base class for all IncDec's * with specialized stuff factored into separate overridable methods */ abstract public class Incdec extends JPanel implements ActionListener { /** * Our internal components that we need to remember */ protected JButton upButton, downButton; protected JLabel label; /** * Our data, initialized inline here */ protected int value = 0; protected int min = 0; protected int max = 100; protected int incr = 1; /** * Only those aspects of initialization that everbody will want */ protected Incdec () { // Put a border on our JPanel // default color, user can modify later setBorder (new LineBorder(Color.RED, 1)); } /** * Pieces of old constructor, factored out here for subclasses to use */ protected void makeUp () { //*1 Chop up old constructor for use by subclasses upButton = new JButton ("+"); //*1 upButton.addActionListener (this); //*1 add (upButton); //*1 } protected void makeDown () { //*2 makeDown, similarly downButton = new JButton ("-"); //*2 downButton.addActionListener (this); //*2 add (downButton); //*2 } protected void makeLabel () { //*3 makeLabel, similarly label = new JLabel (); //*3 label.setHorizontalAlignment (JLabel.CENTER); //*3 refreshLabel (); //*3 add (label); //*3 } /** * Common callback for both buttons, * we use ivar to disambiguate. */ public void actionPerformed (ActionEvent e) { if (e.getSource()==upButton) value += incr; else if (e.getSource()==downButton) value -= incr; // Clamp at bounds if (value > max) value = max; if (value < min) value = min; // Update our widget to match refreshLabel (); } /** * Common code fragment, extracted to here */ protected void refreshLabel() { label.setText (String.valueOf (value)); } /** * Just as an example, we let user customize border color here */ public void setBorderColor (Color color) { setBorder (new LineBorder(color, 1)); } public int getValue() { return value; } }