swing:buttons

Buttons, Check Boxes & Radio Buttons

Για την δημιουργία ενός button μπορείτε να χρησιμοποιήσετε μία κλάση από τις απογόνους της κλάσης javax.swing.AbstractButton, όπως οι JButton, JCheckBox ή JRadioButton. Άλλες υποκλάσεις της κλάσης AbstractButton είναι οι JMenuItem, JCheckBoxMenuItem και JRadioButtonMenuItem τις οποίες θα δούμε στη συνέχεια.

Η κλάση JButton

Δείτε, μεταγλωττίστε και τρέξτε το παρακάτω παράδειγμα από το site της Oracle, το οποίο και θα συζητήσουμε στη συνέχεια.

package components;
 
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
 
/* 
 * ButtonDemo.java requires the following files:
 *   images/right.gif
 *   images/middle.gif
 *   images/left.gif
 */
public class ButtonDemo extends JPanel
            implements ActionListener {
  protected JButton b1, b2, b3;
 
  public ButtonDemo() {
    ImageIcon leftButtonIcon = createImageIcon("images/right.gif");
    ImageIcon middleButtonIcon = createImageIcon("images/middle.gif");
    ImageIcon rightButtonIcon = createImageIcon("images/left.gif");
 
    b1 = new JButton("Disable middle button", leftButtonIcon);
    b1.setVerticalTextPosition(AbstractButton.CENTER);
    b1.setHorizontalTextPosition(AbstractButton.LEADING); //aka LEFT, for left-to-right locales
    b1.setMnemonic(KeyEvent.VK_D);
    b1.setActionCommand("disable");
 
    b2 = new JButton("Middle button", middleButtonIcon);
    b2.setVerticalTextPosition(AbstractButton.BOTTOM);
    b2.setHorizontalTextPosition(AbstractButton.CENTER);
    b2.setMnemonic(KeyEvent.VK_M);
 
    b3 = new JButton("Enable middle button", rightButtonIcon);
    //Use the default text position of CENTER, TRAILING (RIGHT).
    b3.setMnemonic(KeyEvent.VK_E);
    b3.setActionCommand("enable");
    b3.setEnabled(false);
 
    //Listen for actions on buttons 1 and 3.
    b1.addActionListener(this);
    b3.addActionListener(this);
 
    b1.setToolTipText("Click this button to disable the middle button.");
    b2.setToolTipText("This middle button does nothing when you click it.");
    b3.setToolTipText("Click this button to enable the middle button.");
 
    //Add Components to this container, using the default FlowLayout.
    add(b1);
    add(b2);
    add(b3);
  }
 
  public void actionPerformed(ActionEvent e) {
    if ("disable".equals(e.getActionCommand())) {
      b2.setEnabled(false);
      b1.setEnabled(false);
      b3.setEnabled(true);
    } else {
      b2.setEnabled(true);
      b1.setEnabled(true);
      b3.setEnabled(false);
    }
  }
 
  /** Returns an ImageIcon, or null if the path was invalid. */
  protected static ImageIcon createImageIcon(String path) {
    java.net.URL imgURL = ButtonDemo.class.getResource(path);
    if (imgURL != null) {
      return new ImageIcon(imgURL);
    } else {
      System.err.println("Couldn't find file: " + path);
      return null;
    }
  }
 
  /**
   * Create the GUI and show it.  For thread safety, 
   * this method should be invoked from the 
   * event-dispatching thread.
   */
  private static void createAndShowGUI() {
 
    //Create and set up the window.
    JFrame frame = new JFrame("ButtonDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    //Create and set up the content pane.
    ButtonDemo newContentPane = new ButtonDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);
 
    //Display the window.
    frame.pack();
    frame.setVisible(true);
  }
 
  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI(); 
      }
    });
  }
}

Το παραπάνω παράδειγμα απαιτεί την χρήση των παρακάτω εικόνων buttondemoimages.zip. Από τον κώδικα μπορούμε να εξάγουμε τα εξής:

  1. Κάθε button μπορεί να περιέχει κείμενο και ένα εικονίδιο σε αναλογία με τα αντικείμενα τύπου JLabel. Επίσης μπορεί να περιέχει και HTML όπως και τα JLabel (δεν εμφανίζεται στο παραπάνω παράδειγμα).
  2. Για κάθε Button οφείλουμε να ορίσουμε τουλάχιστον ένα αντικείμενο τύπου ActionListener.
  3. Κάθε Button μπορεί να συνδέεται με ένα keyboard shortcut. Για να ορίσετε ένα keyboard shortcut χρησιμοποιήστε τη μέθοδο public void setMnemonic(int c) της κλάσης AbstractButton.

Η κλάση JCheckBox

Ένα check box έχει δύο δυνατές καταστάσεις α) επιλεγμένο και β) απο-επιλεγμένο. Κάθε check box υλοποιείται από την κλάση JCheckBox. Δείτε το παρακάτω παράδειγμα χρήσης της κλάσης JCheckBox από το site της Oracle

CheckBoxDemo.java
package components;
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
/*
 * CheckBoxDemo.java requires 16 image files in the images/geek
 * directory: 
 * geek-----.gif, geek-c---.gif, geek--g--.gif, geek---h-.gif, geek----t.gif,
 * geek-cg--.gif, ..., geek-cght.gif.
 */
public class CheckBoxDemo extends JPanel
              implements ItemListener {
  JCheckBox chinButton;
  JCheckBox glassesButton;
  JCheckBox hairButton;
  JCheckBox teethButton;
 
  /*
   * Four accessory choices provide for 16 different
   * combinations. The image for each combination is
   * contained in a separate image file whose name indicates
   * the accessories. The filenames are "geek-XXXX.gif"
   * where XXXX can be one of the following 16 choices.
   * The "choices" StringBuffer contains the string that
   * indicates the current selection and is used to generate
   * the file name of the image to display.
 
     ----       //zero accessories
 
     c---       //one accessory
     -g--
     --h-
     ---t
 
     cg--       //two accessories
     c-h-
     c--t
     -gh-
     -g-t
     --ht
 
     -ght       //three accessories
     c-ht
     cg-t
     cgh-
 
     cght       //all accessories
   */
 
  StringBuffer choices;
  JLabel pictureLabel;
 
  public CheckBoxDemo() {
    super(new BorderLayout());
 
    //Create the check boxes.
    chinButton = new JCheckBox("Chin");
    chinButton.setMnemonic(KeyEvent.VK_C);
    chinButton.setSelected(true);
 
    glassesButton = new JCheckBox("Glasses");
    glassesButton.setMnemonic(KeyEvent.VK_G);
    glassesButton.setSelected(true);
 
    hairButton = new JCheckBox("Hair");
    hairButton.setMnemonic(KeyEvent.VK_H);
    hairButton.setSelected(true);
 
    teethButton = new JCheckBox("Teeth");
    teethButton.setMnemonic(KeyEvent.VK_T);
    teethButton.setSelected(true);
 
    //Register a listener for the check boxes.
    chinButton.addItemListener(this);
    glassesButton.addItemListener(this);
    hairButton.addItemListener(this);
    teethButton.addItemListener(this);
 
    //Indicates what's on the geek.
    choices = new StringBuffer("cght");
 
    //Set up the picture label
    pictureLabel = new JLabel();
    pictureLabel.setFont(pictureLabel.getFont().deriveFont(Font.ITALIC));
    updatePicture();
 
    //Put the check boxes in a column in a panel
    JPanel checkPanel = new JPanel(new GridLayout(0, 1));
    checkPanel.add(chinButton);
    checkPanel.add(glassesButton);
    checkPanel.add(hairButton);
    checkPanel.add(teethButton);
 
    add(checkPanel, BorderLayout.LINE_START);
    add(pictureLabel, BorderLayout.CENTER);
    setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
  }
 
  /** Listens to the check boxes. */
  public void itemStateChanged(ItemEvent e) {
    int index = 0;
    char c = '-';
    Object source = e.getItemSelectable();
 
    if (source == chinButton) {
      index = 0;
      c = 'c';
    } else if (source == glassesButton) {
      index = 1;
      c = 'g';
    } else if (source == hairButton) {
      index = 2;
      c = 'h';
    } else if (source == teethButton) {
      index = 3;
      c = 't';
    }
 
    //Now that we know which button was pushed, find out
    //whether it was selected or deselected.
    if (e.getStateChange() == ItemEvent.DESELECTED) {
      c = '-';
    }
 
    //Apply the change to the string.
    choices.setCharAt(index, c);
 
    updatePicture();
  }
 
  protected void updatePicture() {
    //Get the icon corresponding to the image.
    ImageIcon icon = createImageIcon(
                  "images/geek/geek-"
                  + choices.toString()
                  + ".gif");
    pictureLabel.setIcon(icon);
    pictureLabel.setToolTipText(choices.toString());
    if (icon == null) {
      pictureLabel.setText("Missing Image");
    } else {
      pictureLabel.setText(null);
    }
  }
 
  /** Returns an ImageIcon, or null if the path was invalid. */
  protected static ImageIcon createImageIcon(String path) {
    java.net.URL imgURL = CheckBoxDemo.class.getResource(path);
    if (imgURL != null) {
      return new ImageIcon(imgURL);
    } else {
      System.err.println("Couldn't find file: " + path);
      return null;
    }
  }
 
  /**
   * Create the GUI and show it.  For thread safety,
   * this method should be invoked from the
   * event-dispatching thread.
   */
  private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("CheckBoxDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    //Create and set up the content pane.
    JComponent newContentPane = new CheckBoxDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);
 
    //Display the window.
    frame.pack();
    frame.setVisible(true);
  }
 
  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}

Θα χρειαστείτε επιπλέον τις φωτογραφίες που περιέχονται στο αρχείο zip geek-images.zip.

Οι κλάσεις ButtonGroup και JRadioButton

Τα radio buttons είναι ανάλογα με τα check boxes με την ιδιαιτερότητα ότι μόνο ένα button μπορεί να είναι επιλεγμένο κάθε φορά. Τα radio buttons οργανώνονται σε button groups. Από τα κουμπιά ενός button group μόνο ένα είναι επιλέξιμο.

Κάθε φορά που ο χρήστης επιλέγει ένα radio button τότε δημιουργείται ένα αντικείμενο τύπου java.awt.events.ActionEvent το οποίο λαμβάνεται από ένα αντικείμενο τύπου ActionListener που συνδέεται με το button. Παράλληλα, δημιουργούνται και δύο αντικείμενα τύπου java.awt.events.ItemEvent ένα αντικείμενο για το button που επιλέχθηκε και ένα αντικείμενο για το button που απο-επιλέχθηκε (εάν υπήρξε τέτοιο), τα οποία λαμβάνονται από ένα αντικείμενο του τύπου ItemListener. Συνήθως χρησιμοποιούμε ItemListeners όπως φαίνεται στο παρακάτω παράδειγμα από το site της Oracle.

RadioButtonDemo.java
package components;
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
/*
 * RadioButtonDemo.java requires these files:
 *   images/Bird.gif
 *   images/Cat.gif
 *   images/Dog.gif
 *   images/Rabbit.gif
 *   images/Pig.gif
 */
public class RadioButtonDemo extends JPanel
               implements ActionListener {
  static String birdString = "Bird";
  static String catString = "Cat";
  static String dogString = "Dog";
  static String rabbitString = "Rabbit";
  static String pigString = "Pig";
 
  JLabel picture;
 
  public RadioButtonDemo() {
    super(new BorderLayout());
 
    //Create the radio buttons.
    JRadioButton birdButton = new JRadioButton(birdString);
    birdButton.setMnemonic(KeyEvent.VK_B);
    birdButton.setActionCommand(birdString);
    birdButton.setSelected(true);
 
    JRadioButton catButton = new JRadioButton(catString);
    catButton.setMnemonic(KeyEvent.VK_C);
    catButton.setActionCommand(catString);
 
    JRadioButton dogButton = new JRadioButton(dogString);
    dogButton.setMnemonic(KeyEvent.VK_D);
    dogButton.setActionCommand(dogString);
 
    JRadioButton rabbitButton = new JRadioButton(rabbitString);
    rabbitButton.setMnemonic(KeyEvent.VK_R);
    rabbitButton.setActionCommand(rabbitString);
 
    JRadioButton pigButton = new JRadioButton(pigString);
    pigButton.setMnemonic(KeyEvent.VK_P);
    pigButton.setActionCommand(pigString);
 
    //Group the radio buttons.
    ButtonGroup group = new ButtonGroup();
    group.add(birdButton);
    group.add(catButton);
    group.add(dogButton);
    group.add(rabbitButton);
    group.add(pigButton);
 
    //Register a listener for the radio buttons.
    birdButton.addActionListener(this);
    catButton.addActionListener(this);
    dogButton.addActionListener(this);
    rabbitButton.addActionListener(this);
    pigButton.addActionListener(this);
 
    //Set up the picture label.
    picture = new JLabel(createImageIcon("images/"
                       + birdString
                       + ".gif"));
 
    //The preferred size is hard-coded to be the width of the
    //widest image and the height of the tallest image.
    //A real program would compute this.
    picture.setPreferredSize(new Dimension(177, 122));
 
 
    //Put the radio buttons in a column in a panel.
    JPanel radioPanel = new JPanel(new GridLayout(0, 1));
    radioPanel.add(birdButton);
    radioPanel.add(catButton);
    radioPanel.add(dogButton);
    radioPanel.add(rabbitButton);
    radioPanel.add(pigButton);
 
    add(radioPanel, BorderLayout.LINE_START);
    add(picture, BorderLayout.CENTER);
    setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
  }
 
  /** Listens to the radio buttons. */
  public void actionPerformed(ActionEvent e) {
    picture.setIcon(createImageIcon("images/"
                    + e.getActionCommand()
                    + ".gif"));
  }
 
  /** Returns an ImageIcon, or null if the path was invalid. */
  protected static ImageIcon createImageIcon(String path) {
    java.net.URL imgURL = RadioButtonDemo.class.getResource(path);
    if (imgURL != null) {
      return new ImageIcon(imgURL);
    } else {
      System.err.println("Couldn't find file: " + path);
      return null;
    }
  }
 
  /**
   * Create the GUI and show it.  For thread safety,
   * this method should be invoked from the
   * event-dispatching thread.
   */
  private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("RadioButtonDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    //Create and set up the content pane.
    JComponent newContentPane = new RadioButtonDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);
 
    //Display the window.
    frame.pack();
    frame.setVisible(true);
  }
 
  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}

Για το παραπάνω παράδειγμα θα χρειαστείτε τις εικόνες animals.zip

swing/buttons.txt · Last modified: 2016/02/26 11:15 (external edit)