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

public class ShowFontsFrameBuffered extends Frame implements ActionListener {
   TextField GetString;
   TextField GetSize;
   Panel InputPanel;
   Button QuitButton;
   String[] fontlist;
   String FontShow = "ABC";
   int FontSize = 10;
   int delta_y = 15;
   int current_width = 450;
   int current_height = 250;
   Image buffer = null;
   Graphics GC;


   public ShowFontsFrameBuffered() {
      super("Fonts Buffered");
      InputPanel = new Panel();
      setLayout(new BorderLayout());
      InputPanel.setLayout(new GridLayout(1,4));
      InputPanel.setBackground(Color.green);
      add("South", InputPanel);
      InputPanel.add(new Label("String:",Label.RIGHT));
      InputPanel.add(GetString = new TextField());
      InputPanel.add(new Label("Size:",Label.RIGHT));
      InputPanel.add(GetSize = new TextField());
      add("North", QuitButton = new Button("Quit"));
      GetSize.setText(""+FontSize);
      GetString.setText(FontShow);
      GetString.addActionListener(this);
      GetSize.addActionListener(this);
      QuitButton.addActionListener(this);
      QuitButton.setBackground(Color.red);
      get_fonts();
      setBackground(Color.yellow);
      setSize(current_width,current_height);
   }

   private void setup_images() {
      int image_width;
      int image_height;
      Insets insets;

      if ( (buffer != null) && (getBounds().width == current_width) &&
           (getBounds().height == current_height) ) return;
      current_width = getBounds().width;
      current_height = getBounds().height;
      insets = getInsets();
      image_width = current_width - insets.left - insets.right;
      image_height = current_height - insets.top - insets.bottom - 
                     InputPanel.getBounds().height - QuitButton.getBounds().height;
      buffer = createImage(image_width,image_height);
      GC = buffer.getGraphics();
      fill_buffer();
   }

   private void fill_buffer() {
      int lm;
      int tm;
      int delta_x;
      int new_inc;
      Graphics g1;
      Font f;
 
      lm = 2;
      tm = 0;
      delta_x = buffer.getWidth(this)/5;
 
      f = GC.getFont();
      new_inc = min_increment(f,0);
      
      g1 = GC.create();
      g1.setColor(Color.yellow);
      g1.fillRect(0,0,buffer.getWidth(this),buffer.getHeight(this));
      g1.setColor(Color.black);
      GC.drawString("Name",lm,tm+delta_y);
      GC.drawString("Plain",lm+delta_x,tm+delta_y);
      GC.drawString("Bold",lm+2*delta_x,tm+delta_y);
      GC.drawString("Italics",lm+3*delta_x,tm+delta_y);
      GC.drawString("Bold Italics",lm+4*delta_x,tm+delta_y);
      for (int i=0;i < fontlist.length;i++) {
           GC.drawString(fontlist[i],lm,tm+(i+2)*delta_y);
              
           f = new Font(fontlist[i],Font.PLAIN,FontSize);
           new_inc = min_increment(f,new_inc);
           g1.setFont(f);
           g1.drawString(FontShow,lm+delta_x,tm+(i+2)*delta_y);
              
           f = new Font(fontlist[i],Font.BOLD,FontSize);
           new_inc = min_increment(f,new_inc);
           g1.setFont(f);
           g1.drawString(FontShow,lm+2*delta_x,tm+(i+2)*delta_y);
              
           f = new Font(fontlist[i],Font.ITALIC,FontSize);
           new_inc = min_increment(f,new_inc);
           g1.setFont(f);
           g1.drawString(FontShow,lm+3*delta_x,tm+(i+2)*delta_y);
              
           f = new Font(fontlist[i],Font.BOLD|Font.ITALIC,FontSize);
           new_inc = min_increment(f,new_inc);
           g1.setFont(f);
           g1.drawString(FontShow,lm+4*delta_x,tm+(i+2)*delta_y);
      }       
      if (delta_y != new_inc) {
         delta_y = new_inc;
         fill_buffer();
      }
   }

   private void get_fonts() {
      Toolkit tk;
      tk = Toolkit.getDefaultToolkit();
      fontlist = tk.getFontList();
   }

   private int min_increment(Font f, int old_inc) {
      FontMetrics fm;
      int inc;
      fm = getFontMetrics(f);
      inc = fm.getMaxAscent() + fm.getMaxDescent() + 2;
      if (inc < old_inc) return old_inc;
      return inc;
   }

   public void paint(Graphics g) {
      int tm;
      int lm;
      Insets insets;

      setup_images();
      insets = getInsets();
      tm = insets.top + QuitButton.getBounds().height;
      lm = insets.left;
      g.drawImage(buffer,lm,tm,this);
   }

   private void reset_it() {
      FontSize = Integer.parseInt(GetSize.getText());
      FontShow = GetString.getText();
      fill_buffer();
      repaint();
   }

   public void actionPerformed (ActionEvent e) {
      if (e.getSource() == GetSize) {
         reset_it();
      }  
      if (e.getSource() == GetString) {
         reset_it();
      }  
      if (e.getSource() == QuitButton) {
         setVisible(false);
      }  

   }

}