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

public class FontSelector
    extends JApplet
{

    // Create the GUI components that represent the font attibutes.
    // It's OK to instantiate the object ahead of time like this.
    Choice familyNames = new Choice();
    JCheckBox bold = new JCheckBox("Bold");
    JCheckBox italic = new JCheckBox("Italic");
    JSlider size = new JSlider(10, 40, 14);
    // Create a place for the user to type in a message.
    JTextField theMessage = new JTextField("Your message here");
    // Create a label to display the final text in the specified font.
    JLabel display = new JLabel();
    JPanel box = new JPanel(new BorderLayout());
    
    public void init()
    {
	// Position GUI components in Applet.
	// We are using two sets of GridBagContraints: one for the
	// left side, and one for the right.  There is no "trick" here,
	// just a way of saving typing.
	Container pane = getContentPane();
	pane.setLayout(new GridBagLayout());
	GridBagConstraints gbc = new GridBagConstraints();
	pane.add(new JLabel("Text:", JLabel.RIGHT), gbc);
	GridBagConstraints gbc2 = new GridBagConstraints();
	gbc2.weightx = 1;
	gbc2.fill = GridBagConstraints.HORIZONTAL;
	gbc2.gridwidth = GridBagConstraints.REMAINDER;
	pane.add(theMessage, gbc2);
	pane.add(new JLabel("Name:", JLabel.RIGHT), gbc);
	pane.add(familyNames, gbc2);
	pane.add(new JLabel("Style:", JLabel.RIGHT), gbc);
	JPanel p = new JPanel(new GridLayout(2, 1));
	p.add(bold, gbc);
	p.add(italic, gbc);
	pane.add(p, gbc2);
	pane.add(new JLabel("Size:", JLabel.RIGHT), gbc);
	pane.add(size, gbc2);
	pane.add(new JLabel("Result:", JLabel.RIGHT), gbc);
	pane.add(display, gbc2);
	pane.add(new JLabel("Result2:", JLabel.RIGHT), gbc);
	pane.add(box, gbc2);
	
	// Update the familyNames so that contains all of the font family names.
	GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
	String[] families = ge.getAvailableFontFamilyNames();
	for (int i=0; i<families.length; i++)
	{
	    familyNames.add(families[i]);
	}
	
	// Add a listener to react to changes in the Choice object.
	familyNames.addItemListener(new ItemListener()
	{
	    public void itemStateChanged(ItemEvent e)
	    {
		updateDisplay();
	    }
	});
	
	// Set the two JCheckBoxes listeners to update the display.
	bold.addActionListener(new ActionListener()
	{
		public void actionPerformed(ActionEvent ae)
		{
		    updateDisplay();
		}
	});
	italic.addActionListener(new ActionListener()
	{
		public void actionPerformed(ActionEvent ae)
		{
		    updateDisplay();
		}
	});
	
	// Update the display when the message changes.
	theMessage.addActionListener(new ActionListener()
	{
		public void actionPerformed(ActionEvent ae)
		{
		    updateDisplay();
		}
	});
	
	// Update the display when the slider changes.
	size.addChangeListener(new ChangeListener()
	{
		public void stateChanged(ChangeEvent ce)
		{
		    updateDisplay();
		}
	});
	// Give the size slider some labels.
	size.setLabelTable(size.createStandardLabels(5));
	size.setPaintLabels(true);
	size.setPaintTicks(true);
	size.setMajorTickSpacing(10);
	size.setMinorTickSpacing(1);
	
	// Initialize the display;
	updateDisplay();
    }
    
    /**
     * updateDisplay will get the font attributes from the GUI components and
     * create a Font object with them.  Then is updates the display with this
     * new font.
     */
    private void updateDisplay()
    {
	// Set the message.
	display.setText(theMessage.getText());
	// Get font family name.
	String family = familyNames.getSelectedItem();
	// Get sytle (bold, italic, or both).  Remember that these styles are
	// additive, meaning that you add them to combine them.
	int style = Font.PLAIN;
	if (bold.isSelected())
	    style += Font.BOLD;
	if (italic.isSelected())
	    style += Font.ITALIC;
	int fontSize = size.getValue();
	// Create the new font.
	Font f = new Font(family, style, fontSize);
	// Set display's font to be the new font.
	display.setFont(f);
	
	// Alternate method.  Still doesn't work right.  Looks like a Java bug!
	box.removeAll();
	JLabel l = new JLabel(theMessage.getText());
	l.setFont(f);
	box.add(l, BorderLayout.CENTER);
    }
    
}

