import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import java.text.*; import java.util.*; /** This class manages a window with up to 7 int fields (numbered 0, ..., 6), * 7 double fields, and 7 string fields, a choice box for locales, and a * "ready" button. The user is expected to type values in fields and then * click the "ready" button. When this button is clicked, method buttonPressed * is called to process the values in the fields and deliver some output, * possibly in the fields in the window. * * Thus, the window is a general GUI, which can be used in a number of * situations. * * To use this class, one needs to write a class X that * * (1) Creates an instance of this class (which we will call "view") * * (2) Registers an ActionListener with the button via the command * view.getButton().addActionListener(this); * * (3) Implements actionPerformed(ActionEvent), which is the only * method in ActionListener. * * This method actionPerformed(ActionEvent) is called when the "ready" * button is pressed. In this method, place any code you like to read the * values of the fields, calculate, and store values in the fields. To * read the fields, use methods getIntField, getDoubleField, and * getStringField. To store values in the fields, use methods setIntField, * setDoubleField, and setStringField. */ public class GenericGUI extends JFrame { // constants // TOTAL_MAX_FIELDS: max number of fields of one type that is allowed private static final int TOTAL_MAX_FIELDS= 7; private static final int MAX_FIELD_LENGTH= 20; private static final int ROW_SEPARATION= 10; private static final int COLUMN_SEPARATION= 15; // maxFields: actual max number of fields used of one type. private static int maxFields; // fields private JTextField[] intFields; // the fields that can contain ints private JTextField[] doubleFields; // the fields that can contain doubles private JTextField[] stringFields; // the fields that can contain text private int numInts; // number of int fields private int numDoubles; // number of double fields private int numStrings; // number of text fields // the button private JButton theButton; // These variables are used to provide the choicebox of locales private Locale locale= Locale.getDefault(); private Locale[] locales= Calendar.getAvailableLocales(); // array of all locales private JComboBox choiceBox; /** Constructor: a GUI window with * max( min(i,MAX_FIELDS), 0) int fields, * max( min(d,MAX_FIELDS), 0) double fields, * max( min(s,MAX_FIELDS), 0) String fields, * and a "ready" button */ public GenericGUI(int i, int d, int s) { super("Generic GUI"); numInts = Math.max( Math.min(i,TOTAL_MAX_FIELDS), 0); numDoubles = Math.max( Math.min(d,TOTAL_MAX_FIELDS), 0); numStrings = Math.max( Math.min(s,TOTAL_MAX_FIELDS), 0); maxFields = Math.max( Math.max(numInts,numDoubles), numStrings ); intFields = new JTextField[maxFields]; doubleFields = new JTextField[maxFields]; stringFields = new JTextField[maxFields]; createFields(); theButton = createActionButton(); // Tell the program to exit upon closure of this window setDefaultCloseOperation(EXIT_ON_CLOSE); // Add the Panel of fields and the button to this window getContentPane().setLayout(new BorderLayout()); choiceBox = createChoiceBox(); getContentPane().add(choiceBox,BorderLayout.NORTH); getContentPane().add(createPanel(),BorderLayout.CENTER); getContentPane().add(theButton,BorderLayout.SOUTH); } /** Create elements of arrays intFields, doubleFields, and stringFields */ private void createFields() { //inv: elts 0..i-1 have been added to each array for(int i= 0; i< maxFields; i++) { intFields[i] = new JTextField(MAX_FIELD_LENGTH); doubleFields[i] = new JTextField(MAX_FIELD_LENGTH); stringFields[i] = new JTextField(MAX_FIELD_LENGTH); } } /** Yields: the panel of fields that goes in this window */ private JPanel createPanel() { JPanel panel= new JPanel(); panel.setLayout(new GridLayout(1, 3, COLUMN_SEPARATION, 0)); if (numInts > 0) { panel.add(createFieldsPanel(numInts, intFields, "Integer fields")); } if (numDoubles > 0) { panel.add(createFieldsPanel(numDoubles, doubleFields, "Double fields")); } if (numStrings > 0) { panel.add(createFieldsPanel(numStrings, stringFields, "String fields")); } return panel; } /** Yields: a Panel with visible elements a[0..n-1], invisible elements * a[n..maxFields-1] (to make the vertical sizes nice), and with * title t above them. * Pre: n > 0 */ private JPanel createFieldsPanel(int n, JTextField[] a, String t) { JPanel panel= new JPanel(); panel.setLayout(new GridLayout(maxFields+1, 1, 0, ROW_SEPARATION)); panel.add(new JLabel(t, JLabel.CENTER)); //inv: elts 0..i-1 have been added for (int i= 0; i < n; i++) { panel.add(a[i]); } // Add the invisible elements. // inv: items n..i-1 invisible elts have been added for (int i=n; i < maxFields; i++) { panel.add(a[i]); a[i].setVisible(false); } return panel; } /** Yields: a button with title "Ready!" */ private JButton createActionButton() { JButton button= new JButton("Ready!"); return button; } /** Yields: the choiceBox to contain locales */ private JComboBox createChoiceBox() { JComboBox cb = new JComboBox(); // Add the locales to cb // inv: items 0..i-1 have been added for (int i= 0; i != locales.length; i++) { cb.addItem(locales[i].getDisplayName()); } // Set the selected item to the default // inv: items 0..i-1 have been set to default for (int i= 0; i != locales.length; i++) { if (locale.equals(locales[i])) { cb.setSelectedIndex(i); } } return cb; } /** Pack and show this window */ public void showWindow() { pack(); setVisible(true); } // public methods to access the gui components /** Yields: the integer in int field number f, or 0 if either f is not * valid or the field doesn't contain an integer. */ public int getIntField(int f) { try { return Integer.parseInt( intFields[f].getText() ); } catch (ArrayIndexOutOfBoundsException e) { return 0; } catch (NumberFormatException e) { intFields[f].setText("" + intFields[f].getText() +": NOT AN INTEGER, 0 used"); return 0; } } /** Set int field number f to m. No effect if f is not valid. */ public void setIntField(int f, int m) { try { intFields[f].setText("" + m); } catch (ArrayIndexOutOfBoundsException e) { return; } } /** Yields: the double in double field number f, or 0 if either f is not * valid or the field doesn't contain a double. */ public double getDoubleField(int f) { try { return Double.valueOf( doubleFields[f].getText() ).doubleValue(); } catch (ArrayIndexOutOfBoundsException e) { return 0; } catch (NumberFormatException e) { doubleFields[f].setText("" + doubleFields[f].getText() +": NOT A DOUBLE, 0 used"); return 0; } } /** Set double field number f to d. No effect if f is not valid. */ public void setDoubleField(int f, double d) { try { doubleFields[f].setText("" + d); } catch (ArrayIndexOutOfBoundsException e) { return; } } /** Yields: the string in string field number f, or "" if f is not valid. */ public String getStringField(int f) { try { return stringFields[f].getText(); } catch (ArrayIndexOutOfBoundsException e) { return ""; } } /** Set string field number f to s. No effect if f is not valid. */ public void setStringField(int f, String s) { try { stringFields[f].setText("" + s); } catch (ArrayIndexOutOfBoundsException e) { return; } } /** Yields: the "ready" button. Needed to hook up ActionListener */ public JButton getButton() { return theButton; } /** Yields:the locale that was selected from the choice box (the default, if none) */ public Locale getLocale() { return locales[choiceBox.getSelectedIndex()]; } }