// // another example of the Java AWT, showing different ways to process // changes in TextArea Objects. // see class definition for details. // // observation suggests that on some systems, when "all" is chosen // this program may not be able to keep up with a fast-typing // user, leading to very strange behavior (jumbled-up text in // the TextArea being edited). // import java.awt.* ; import java.awt.event.* ; import java.util.StringTokenizer ; // // a MirrorArea object is a CloseableFrame containing two TextArea // objects whose contents are to be kept "in sync" (equivalent). // if syncOnAll = true, the fields are resynchronized every time // one of them changes; otherwise they are resynchronized when // (1) the number of lines of text changes in the field receiving // keyboard input, or (2) the user clicks the mouse button in one // of the fields. // class MirrorArea extends CloseableFrame { MirrorArea(boolean syncOnAll) { super("MirrorArea") ; setLayout(new GridLayout(2, 1)) ; String startString = "Hello!" ; int startWidth = 40 ; int startHeight = 4 ; TextArea t1 = new TextArea( startString, startHeight, startWidth) ; TextArea t2 = new TextArea( startString, startHeight, startWidth) ; add(t1) ; add(t2) ; if (syncOnAll) { // one adapter has source t1 and target t2; // other has source t2 and target t1. t1.addTextListener(new SyncAllAdapter(t2)) ; t2.addTextListener(new SyncAllAdapter(t1)) ; } else { // one set of adapters has source t1, target t2; // other has source t2, target t1. t1.addTextListener(new SyncReturnAdapter(t2)) ; t2.addTextListener(new SyncReturnAdapter(t1)) ; t1.addMouseListener(new SyncClickAdapter(t2)) ; t2.addMouseListener(new SyncClickAdapter(t1)) ; } pack() ; show() ; } // // ---- main --------------------------------------------------- // // command-line argument: all/return // "all" -> syncOnAll = true (see comments for class). // "return" -> syncOnAll = false. // public static void main(String[] args) { if (args.length < 1) { System.out.println("Argument is all/return") ; System.exit(-1) ; } boolean syncOnAll = false ; if (args[0].equals("all")) { syncOnAll = true ; } else if (!args[0].equals("return")) { System.out.println("Argument is all/return") ; System.exit(-1) ; } MirrorArea m = new MirrorArea(syncOnAll) ; } // // ---- inner classes ------------------------------------------ // // // a SyncAllAdapter object resyncs its target and source // TextArea objects every time the source's text changes. // class SyncAllAdapter implements TextListener { TextArea target ; SyncAllAdapter(TextArea t) { target = t ; } public void textValueChanged(TextEvent e) { TextArea src = (TextArea) e.getSource() ; if (!target.getText().equals(src.getText())) { target.setText(src.getText()) ; } } } // // a SyncReturnAdapter object resyncs its target and source // TextArea objects every time the number of lines in the // source's text changes. // class SyncReturnAdapter implements TextListener { TextArea target ; SyncReturnAdapter(TextArea t) { target = t ; } public void textValueChanged(TextEvent e) { TextArea src = (TextArea) e.getSource() ; int srcLines = countNewLines(src.getText()) ; int targetLines = countNewLines(target.getText()) ; if (srcLines != targetLines) target.setText(src.getText()) ; } private int countNewLines(String s) { StringTokenizer st = new StringTokenizer(s, "\n", true) ; int count = 0 ; while (st.hasMoreTokens()) { if (st.nextToken().equals("\n")) count++ ; } return count ; } } // // a SyncClickAdapter object resyncs its target and source // TextArea objects every time the mouse is clicked in the // source area. // class SyncClickAdapter extends MouseAdapter { TextArea target ; SyncClickAdapter(TextArea t) { target = t ; } public void mouseClicked(MouseEvent e) { TextArea src = (TextArea) e.getSource() ; if (!target.getText().equals(src.getText())) target.setText(src.getText()) ; } } }