// ChoiceFrame.java
// A program from Cay Horstmann's Computing Concepts with Java 2 Essentials
// Adapted by Scot Drysdale.  Comments and various changes by THC.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class ChoiceFrame extends JFrame {
  private static final long serialVersionUID = 1L;
  
  private JTextField sampleField;       // holds a text sample
  private JCheckBox editableCheckBox;   // is the text sample editable?
  private JCheckBox italicCheckBox;     // showing the text sample in italics?
  private JCheckBox boldCheckBox;       // showing the text sample in bold?
  private JRadioButton smallButton;     // showing the text sample in small chars?
  private JRadioButton mediumButton;    // medium sized chars?
  private JRadioButton largeButton;     // large chars?
  private JComboBox fontnameCombo;      // combo box for font names

  private final int SMALL_SIZE = 16;
  private final int MEDIUM_SIZE = 24;
  private final int LARGE_SIZE = 32;

  public ChoiceFrame() {  
    final int DEFAULT_FRAME_WIDTH = 500;
    final int DEFAULT_FRAME_HEIGHT = 400;
    setSize(DEFAULT_FRAME_WIDTH, DEFAULT_FRAME_HEIGHT);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    // There is just one listener for all events.
    // It will just run through all the choices and redisplay the text sample
    // according to the current choices.
    ChoiceListener listener = new ChoiceListener();

    // Construct the components.
    // Start with the sample text and whether it's editable.
    sampleField = new JTextField("Call me Ishmael");
    sampleField.setEditable(false);       // stops user from changing text field
    editableCheckBox = new JCheckBox("Editable");
    editableCheckBox.setToolTipText("Makes the text editable");
    editableCheckBox.addActionListener(listener);
    
    // The various font name choices.
    fontnameCombo = new JComboBox();
    fontnameCombo.addItem("Times");
    fontnameCombo.addItem("Helvetica");
    fontnameCombo.addItem("Courier");
    fontnameCombo.setEditable(true);      // user can add own choices
    fontnameCombo.setToolTipText("Changes the font used to display the text");
    fontnameCombo.addActionListener(listener);

    // Check boxes for italic and bold.  Any subset of them may be checked.
    italicCheckBox = new JCheckBox("Italic");
    italicCheckBox.setToolTipText("Displays the text in italic font");
    italicCheckBox.addActionListener(listener);
    boldCheckBox = new JCheckBox("Bold");
    boldCheckBox.setToolTipText("Displays the text in bold font");
    boldCheckBox.addActionListener(listener);

    // Radio buttons for the character sizes.  Initially, large is selected.
    smallButton = new JRadioButton("Small");
    smallButton.setToolTipText("Displays the text in " + SMALL_SIZE + "-point font");
    smallButton.addActionListener(listener);

    mediumButton = new JRadioButton("Medium");
    mediumButton.setToolTipText("Displays the text in " + MEDIUM_SIZE + "-point font");
    mediumButton.addActionListener(listener);

    largeButton = new JRadioButton("Large");
    largeButton.setSelected(true);
    largeButton.setToolTipText("Displays the text in " + LARGE_SIZE + "-point font");
    largeButton.addActionListener(listener);

    // Add the radio buttons to a button group to ensure that
    // only one button is selected at a time.
    ButtonGroup sizeGroup = new ButtonGroup();
    sizeGroup.add(smallButton);
    sizeGroup.add(mediumButton);
    sizeGroup.add(largeButton);

    // Add components to panels.
    // Make a panel to hold the check box for editability and the text sample.
    JPanel sampleFrame = new JPanel();
    sampleFrame.setLayout(new BorderLayout());
    sampleFrame.add(sampleField, BorderLayout.CENTER);
    sampleFrame.add(editableCheckBox, BorderLayout.NORTH);    

    // Now a panel for the font name combo box.
    JPanel fontnamePanel = new JPanel();
    fontnamePanel.add(fontnameCombo);

    // A panel for the size radio buttons.  Put a titled and etched border around it.
    JPanel sizeGroupPanel = new JPanel();
    sizeGroupPanel.add(smallButton);
    sizeGroupPanel.add(mediumButton);
    sizeGroupPanel.add(largeButton);
    sizeGroupPanel.setBorder(new TitledBorder(new EtchedBorder(), "Size"));

    // A panel for style: italic and bold.  Put a titled and etched border around it.
    JPanel styleGroupPanel = new JPanel();
    styleGroupPanel.add(italicCheckBox);
    styleGroupPanel.add(boldCheckBox);
    styleGroupPanel.setBorder(new TitledBorder(new EtchedBorder(), "Style"));

    // Line up the component panels.
    // Make the font name, size, and style panels line up vertically, using
    // a Box Layout manager.
    JPanel southPanel = new JPanel();
    southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
    southPanel.add(fontnamePanel);
    southPanel.add(sizeGroupPanel);
    southPanel.add(styleGroupPanel);

    // Add the two remaining panels to the content pane.
    Container contentPane = getContentPane();
    contentPane.add(sampleFrame, BorderLayout.CENTER);
    contentPane.add(southPanel, BorderLayout.SOUTH);
    
    // Display our sample.
    setSampleFont();
  }

  // Gets user choice for editability, font name, style, and size.
  // Then displays the sample text.
  public void setSampleFont() {
    // Is the sample editable?
    sampleField.setEditable(editableCheckBox.isSelected());
    
    // Get the font name.
    String fontname = (String) fontnameCombo.getSelectedItem();
      
    // Get the font style.
    int style = 0;
    if (italicCheckBox.isSelected()) 
      style = style + Font.ITALIC;
    if (boldCheckBox.isSelected()) 
      style = style + Font.BOLD;
       
    // Get the font size.
    int size = 0;

    if (smallButton.isSelected()) 
      size = SMALL_SIZE;
    else if (mediumButton.isSelected()) 
      size = MEDIUM_SIZE;
    else if (largeButton.isSelected()) 
      size = LARGE_SIZE;
       
    // Set the font of the text field, given all that we have determined.      
    sampleField.setFont(new Font(fontname, style, size));
    
    // And redisplay it.     
    sampleField.repaint();
  }
  
  // Class to act as a listener for all button and checkbox events.
  private class ChoiceListener implements ActionListener {  
    public void actionPerformed(ActionEvent event) {  
      setSampleFont();
    }
  }
}