import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.AbstractListModel;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.Container;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class MultiplicationTable extends JFrame
{
   private MultiplicationModel multModel;

   MultiplicationTable (String title, MultiplicationModel model)
   {
      super(title);
      multModel = model;
      Container content = getContentPane();
      content.setLayout(new BorderLayout());
      content.add(new JScrollPane(new JList(model)), BorderLayout.CENTER);
      JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
      inputPanel.add(new JLabel("Show multiples of: "));
      JTextField inputField = new JTextField(5);
      inputPanel.add(inputField);
      inputField.addActionListener(
            new ActionListener()
            {
               public void actionPerformed (ActionEvent e)
               {
                  String input = e.getActionCommand();
                  try
                  {
                     int value = Integer.parseInt(input);
                     if (value > 0) multModel.setBase(value);
                  }
                  catch (NumberFormatException nfe)
                  {
                     Toolkit.getDefaultToolkit().beep();
                  }
               }
            }
      );
      inputPanel.add(inputField);
      content.add(inputPanel, BorderLayout.SOUTH);
      setDefaultCloseOperation(DISPOSE_ON_CLOSE);
      pack();
      setVisible(true);
   }

   public static void main (String[] args)
   {
      new MultiplicationTable("Multiplication Table", new MultiplicationModel());
      MultiplicationModel shared = new MultiplicationModel();
      new MultiplicationTable("Shared Model 1", shared);
      new MultiplicationTable("Shared Model 2", shared);

   }
}

class MultiplicationModel extends AbstractListModel
{
   private static final int NUMBER_OF_ROWS = 1000;
   private int baseNumber = 7;

   public int getSize ()
   {
      return NUMBER_OF_ROWS;
   }

   public Object getElementAt (int index)
   {
      int factor = index + 1;
      return factor + " * " + baseNumber + " = " + (factor * baseNumber);
   }

   void setBase (int base)
   {
      if (base != baseNumber)
      {
         baseNumber = base;
         fireContentsChanged(this, 0, NUMBER_OF_ROWS - 1);
      }
   }
}
