/** * EditableStringWindow.java * Copyright: Yuan Chen * * Minor modifications: Jason Eisner * * A little GUI editor to test the EditableString class you wrote in * the homework. */ import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import java.lang.Character; import java.awt.*; import java.awt.event.*; public class EditableStringWindow extends JFrame { /*EditableString, the object handling the word processing*/ private final EditableString estring; /* we save the text here so that we can redisplay the last * good state if the stack fills up. */ private String windowtext; /* The text area for word processor*/ private JTextArea textArea; /* The label for search status*/ private JLabel label; /* The text field for inputing search string*/ private JTextField searchField; /*Constructor, initialize all areas in the window *and handle events from window */ public EditableStringWindow(EditableString es) { /*Set the name of the window, super() must be *called as the first line of the constructor */ super("This is an instance of EditableStringWindow"); /*initialize all objects needed in this window*/ textArea = new JTextArea(17,35); estring = es; redisplay(); label = new JLabel("status"); searchField = new JTextField(15); /*Panel for search*/ JPanel panel = new JPanel(); /*search button*/ JButton search = new JButton("Search"); /* Add the window listener to receive events where the * window was closed or activated. We exit the application * if any window is closed. We refresh the window when it * is activated, in case we have been editing the underlying * EditableString in some other window. */ addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.out.println("You closed a window, so I'm going to quit."); System.exit(0); //exit the application } public void windowActivated(WindowEvent e) { redisplay(); } }); textArea.setEditable(false); /*add search field and button to panel*/ panel.add(searchField); panel.add(search); /*add key listener to receive ENTER event from search field which *will activate the search */ searchField.addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent e) { if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) { if(estring.search(searchField.getText())) label.setText("Status: Found \"" + searchField.getText() + "\""); else label.setText("Status: Fail! Can't find \""+ searchField.getText() + "\""); searchField.setText(""); redisplay(); } } }); /*add action listener to receive button clicked event from search button *which will activate the search */ search.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { if(estring.search(searchField.getText())) label.setText("Status: Found \"" + searchField.getText() + "\""); else label.setText("Status: Fail! Can't find \""+ searchField.getText() + "\""); searchField.setText(""); redisplay(); } }); /*set the line-wrapping to be ture, so that the lines will be wrapped * if they are too long to fit within the allocated width. */ textArea.setLineWrap(true); /*set the caret color to be white, so you can't see the caret in the text area*/ textArea.setCaretColor(new Color(255,255,255)); /*set font in text area to be BOLD, size is 16*/ textArea.setFont(new Font("default",java.awt.Font.BOLD, 16)); /*the scroll pane includes text area*/ JScrollPane scrollPane = new JScrollPane(textArea); /*add key listener to receive key events from text area * and active relevant methods in EditableString to process */ textArea.addKeyListener(new KeyAdapter(){ public void keyPressed(KeyEvent e){ textArea.setText(""); label.setText("Status"); try { switch(e.getKeyCode()) { case java.awt.event.KeyEvent.VK_BACK_SPACE: estring.backspace(); break; case java.awt.event.KeyEvent.VK_ESCAPE: System.exit(0); case java.awt.event.KeyEvent.VK_END: estring.moveToEnd(); break; case java.awt.event.KeyEvent.VK_HOME: estring.moveToStart(); break; case java.awt.event.KeyEvent.VK_LEFT: estring.moveLeft(); break; case java.awt.event.KeyEvent.VK_RIGHT: estring.moveRight(); break; case java.awt.event.KeyEvent.VK_DELETE: estring.delete(); break; default: if (e.getKeyChar() == java.awt.event.KeyEvent.CHAR_UNDEFINED) { // some non-character event we don't handle, like up arrow java.awt.Toolkit.getDefaultToolkit().beep(); } else { // a real character; estring.insertChar(e.getKeyChar()); } } } catch (StackFullException ex) { label.setText("Status: "+ex+" ... will *try* to continue"); } redisplay(); } }); /*Set the frame to be unresizable*/ setResizable(false); /*add panel, scroll pane and label into this window contentPane*/ getContentPane().add(panel,BorderLayout.NORTH); getContentPane().add(scrollPane, BorderLayout.CENTER); getContentPane().add(label, BorderLayout.SOUTH); /*size the frame so that all its contents are at or above *their preferred sizes */ pack(); } /* Redisplay the text and give it the focus. We try to make * sure this works even if toStringCursor throws an exception. */ private void redisplay() { String s; try { s = estring.toStringCursor(); windowtext = s; // save in case of later problem } catch (StackFullException ex) { label.setText("Status: "+ex+" ... will *try* to continue"); // revert to last saved state s = windowtext; } textArea.setText(s); textArea.requestFocus(); } /** A test method for this class. We can take one * command-line argument, which is the number of windows * to show on our string. */ public static void main(String[] args) { // Read command-line arguments int wins = 1; if (args.length > 0) { try { wins = Integer.parseInt(args[0]); } catch (NumberFormatException e) { } } System.out.println("Number of window instances = "+wins); System.out.println(" To change this, specify it as a command-line argument,"); System.out.println(" e.g., java EditableStringWindow 2"); // Create 1 or more windows for editing the SAME EditableString EditableString es = new EditableString("Stacks are wack!",""); EditableStringWindow[] winarray = new EditableStringWindow[wins]; for (int i=0; i < wins; i++) { winarray[i] = new EditableStringWindow(es); winarray[i].show(); } } }