package edu.princeton.toy; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import edu.princeton.swing.*; import edu.princeton.swing.text.*; public class TExampleDialog extends JDialog implements ActionListener, ListSelectionListener { /** * The number of rows titles which will be shown by the title selection. */ public static final int TITLE_ROWS = 7; /** * The maximum number of rows of the text which will be shown by the description. */ public static final int DESCRIPTION_ROWS = 7; private static final String CLASS_STRING = TExampleDialog.class.toString(); public static final String OPEN_COMMAND = CLASS_STRING + "#openCommand"; public static final String CANCEL_COMMAND = CLASS_STRING + "#cancelCommand"; public static final String UPDATE_COMMAND = CLASS_STRING + "#updateCommand"; private String selection[]; private int lastSelectedIndex; private PHighlightedTextArea textArea; private PWrappedList list; private TProgramDocument program; private JButton openButton; /** * Creates a new TExampleDialog, centered in the screen. */ private TExampleDialog(Frame parent) { super(parent, "Open Example Program", true); } /** * Creates a new TExampleDialog, centered in the screen. */ private TExampleDialog(Dialog parent) { super(parent, "Open Example Program", true); } /** * Called by the constructors to init the JDialog properly. */ protected void dialogInit() { super.dialogInit(); // Prepare the menu JMenuBar menuBar; JMenu menu; JMenuItem menuItem; menuBar = new JMenuBar(); setJMenuBar(menuBar); { // Build the edit menu menu = new JMenu("Edit"); menu.setMnemonic(KeyEvent.VK_E); menuBar.add(menu); menu.add(ClipboardTargetManager.CUT_ACTION.createMenuItem()); menu.add(ClipboardTargetManager.COPY_ACTION.createMenuItem()); menu.add(ClipboardTargetManager.PASTE_ACTION.createMenuItem()); menu.addSeparator(); menu.add(ClipboardTargetManager.SELECT_ALL_ACTION.createMenuItem()); } // Build the dialog's contents Container contentPane = getContentPane(); contentPane.setLayout(new GridBagLayout()); // Add the examples label contentPane.add( new JLabel("Available Examples:", SwingConstants.LEFT), new GridBagConstraints( 0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0 ) ); { // Prepare the example list String exampleTitles[] = new String[TExampleManager.getExampleCount()]; for (int ctr = 0; ctr < exampleTitles.length; ctr++) exampleTitles[ctr] = TExampleManager.getExampleTitle(ctr); list = new PWrappedList(exampleTitles); list.addActionListener(this); list.setActionCommand(OPEN_COMMAND); list.setVisibleRowCount(TITLE_ROWS); list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); list.addListSelectionListener(this); contentPane.add( new JScrollPane( list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ), new GridBagConstraints( 0, 1, 2, 1, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0 ) ); } // Add the preview label contentPane.add( new JLabel("Preview:", SwingConstants.LEFT), new GridBagConstraints( 0, 2, 2, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0 ) ); { // Prepare the Example preview area program = new TProgramDocument(""); textArea = new PHighlightedTextArea( program, DESCRIPTION_ROWS, TProgramDocument.OUTSIDE_MARGIN_COLUMN + 2 ); textArea.setEditable(false); textArea.setHighlightedLine(PHighlightedTextArea.NEVER_HIGHLIGHT); TOptionsFrame.registerComponent(textArea, TOptionsFrame.PROGRAM_AREA_INDEX); TOptionsFrame.registerHighlightedTextArea(textArea); int columnMarkers[] = new int[3]; columnMarkers[0] = 8; columnMarkers[1] = TProgramDocument.COMMENT_COLUMN; columnMarkers[2] = TProgramDocument.OUTSIDE_MARGIN_COLUMN; textArea.setColumnMarkers(columnMarkers); contentPane.add( textArea, new GridBagConstraints( 0, 3, 2, 1, 0.0, 0.1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0 ) ); } // Add the spacer to the left of the button panel contentPane.add( new PSpacer(1, 1), new GridBagConstraints( 0, 4, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0 ) ); { // Prepare the button panel JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 4, 0)); JButton button = new JButton("Open"); button.addActionListener(this); button.setActionCommand(OPEN_COMMAND); openButton = button; buttonPanel.add(button); button = new JButton("Cancel"); button.addActionListener(this); button.setActionCommand(CANCEL_COMMAND); buttonPanel.add(button); contentPane.add( buttonPanel, new GridBagConstraints( 1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(2, 2, 2, 2), 0, 0 ) ); } doCommand(UPDATE_COMMAND, null); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); setResizable(false); pack(); Window owner = getOwner(); setLocation( owner.getX() + owner.getWidth() / 2 - getWidth() / 2, owner.getY() + owner.getHeight() / 2 - getHeight() / 2 ); lastSelectedIndex = -1; selection = null; } /** * Override dispose() to also unregister the program text area. */ public void dispose() { TOptionsFrame.unregisterComponent(textArea, TOptionsFrame.PROGRAM_AREA_INDEX); TOptionsFrame.registerHighlightedTextArea(textArea); super.dispose(); } /** * Shows a TExampleDialog and returns the text of the selected examples. * * @param The parent of the dialog. This must be an instance of java.awt.Frame or * java.awt.Dialog. * @return An array containing the text of the selected examples, null if nothing was selected. */ public static String[] showExampleDialog(Window parent) { if (parent == null) throw new NullPointerException(); TExampleDialog dialog; if (parent instanceof Frame) dialog = new TExampleDialog((Frame)parent); else dialog = new TExampleDialog((Dialog)parent); dialog.setVisible(true); String selection[] = dialog.selection; dialog.dispose(); return selection; } /** * Performs a command based on the argument. * * @param command An object representing the command. Note that pointer equality (not string * equality) is tested here, so it is important to use the string constants defined in this * class. An IllegalArgumentException will be thrown if the argument is invalid. * @param extraInfo Any extra information necessary. * @return True iff the command was executed sucessfully. */ public boolean doCommand(String command, Object extraInfo) { //////////////////////////////////////////////////////////////////////////////////////////// if (command == OPEN_COMMAND) { int selectedIndices[] = list.getSelectedIndices(); int length = selectedIndices.length; selection = new String[length]; for (int ctr = 0; ctr < length; ctr++) selection[ctr] = TExampleManager.getExampleText(selectedIndices[ctr]); setVisible(false); return true; } //////////////////////////////////////////////////////////////////////////////////////////// if (command == CANCEL_COMMAND) { selection = null; setVisible(false); return true; } //////////////////////////////////////////////////////////////////////////////////////////// if (command == UPDATE_COMMAND) { int selectedIndex = list.getSelectedIndex(); if (selectedIndex != lastSelectedIndex) { if (selectedIndex == -1) { program.setText(""); openButton.setEnabled(false); lastSelectedIndex = selectedIndex; } else { program.setText(TExampleManager.getExampleText(selectedIndex)); openButton.setEnabled(true); lastSelectedIndex = selectedIndex; } } return true; } throw new IllegalArgumentException(); } /** * Implement ActionListener to pass the command onto doCommand(). * * @see #doCommand(String, Object) */ public void actionPerformed(ActionEvent e) { doCommand(e.getActionCommand(), null); } /** * Implement ListSelectionListener to pass an update command onto doCommand(). * * @see #doCommand(String, Object) */ public void valueChanged(ListSelectionEvent e) { doCommand(UPDATE_COMMAND, null); } }