From f71deee73a84644012191e739b42127956d359fc Mon Sep 17 00:00:00 2001 From: benfry Date: Mon, 18 Nov 2002 21:48:14 +0000 Subject: [PATCH] ironed out several problems with text editor --- app/KjcEngine.java | 31 ++------- app/PdeEditor.java | 79 ++++++++++++++++++++- app/PdeEditorConsole.java | 24 ++++--- app/PdeEditorListener.java | 137 +++++++++++++++++++++++++++++-------- app/PdeEditorTextPane.java | 8 ++- todo.txt | 34 ++++++--- 6 files changed, 234 insertions(+), 79 deletions(-) diff --git a/app/KjcEngine.java b/app/KjcEngine.java index df433bf6f..534d8deb5 100644 --- a/app/KjcEngine.java +++ b/app/KjcEngine.java @@ -6,30 +6,6 @@ import java.net.*; // the start of a bad joke import com.oroinc.text.regex.*; -/* - -this needs to be reworked. there are three essential parts - -(0. if not java, then use another 'engine'.. i.e. python) - -1. do the p5 language preprocessing - -> this creates a working .java file in a specific location - -2. compile the code from that location - -| catching errors along the way - -| currently done with kjc, but would be nice to use jikes - -> placing it in a ready classpath, or .. ? - -3. run the code - needs to communicate location for window - and maybe setup presentation space as well - -> currently done internally - -> would be nice to use external (at least on non-os9) - -afterwards, some of these steps need a cleanup function - - */ - // always compile to lib directory // always make .java in current directory @@ -239,9 +215,9 @@ public class KjcEngine extends PdeEngine { for (int i = 0; i < imports.length; i++) { writer.print("import " + imports[i] + ".*; "); // add serial if running inside pde - if (kjc) writer.print("import javax.comm.*;"); if (!kjc) writer.println(); } + if (kjc) writer.print("import javax.comm.*;"); if (!kjc) writer.println(); writer.print("public class " + name + " extends " + @@ -490,7 +466,10 @@ public class KjcEngine extends PdeEngine { int messageLineCount; public void message(String s) { - //System.out.println(messageMode + " " + "msg: " + s); + // as in: lib\build\Temporary_5476_6442.java:88: caution:Assignment of an expression to itself [KOPI] + if (s.indexOf("caution") != -1) return; + + System.out.println(messageMode + " " + "msg: " + s); if (messageMode == COMPILING) { //System.out.println("leech2: " + new String(b, offset, length)); diff --git a/app/PdeEditor.java b/app/PdeEditor.java index c9dff9b33..8ee595fae 100644 --- a/app/PdeEditor.java +++ b/app/PdeEditor.java @@ -82,6 +82,8 @@ public class PdeEditor extends Panel { PdeBase base; + // hack until i have a better text editor + public PdeEditor(PdeBase base) { this.base = base; @@ -147,10 +149,11 @@ public class PdeEditor extends Panel { add("Center", rightPanel); // hopefully these are no longer needed w/ swing - //PdeEditorListener listener = new PdeEditorListener(this); - //textarea.addKeyListener(listener); + PdeEditorListener listener = new PdeEditorListener(this); + textarea.addKeyListener(listener); //textarea.addFocusListener(listener); + /* textarea.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent event) { // don't do things if the textarea isn't editable @@ -171,8 +174,56 @@ public class PdeEditor extends Panel { setSketchModified(true); } } + + + case 9: // expand tabs + if (expandTabs) { + //System.out.println("start = " + tc.getSelectionStart()); + //System.out.println("end = " + tc.getSelectionEnd()); + //System.out.println("pos = " + tc.getCaretPosition()); + tc.replaceRange(tabString, tc.getSelectionStart(), + tc.getSelectionEnd()); + event.consume(); + } + break; + + case 10: // auto-indent + case 13: + if (autoIndent) { + //System.err.println("auto indenting"); + char contents[] = tc.getText().toCharArray(); + // back up until \r \r\n or \n.. @#($* cross platform + //index = contents.length-1; + int index = tc.getCaretPosition() - 1; + int spaceCount = 0; + boolean finished = false; + while ((index != -1) && (!finished)) { + if ((contents[index] == '\r') || + (contents[index] == '\n')) { + finished = true; + } else { + spaceCount = (contents[index] == ' ') ? + (spaceCount + 1) : 0; + } + index--; + } + + // !@#$@#$ MS VM doesn't move the caret position to the + // end of an insertion after it happens, even though sun does + String insertion = newline + spaces.substring(0, spaceCount); + int oldCarrot = tc.getSelectionStart(); + tc.replaceRange(insertion, oldCarrot, tc.getSelectionEnd()); + // microsoft vm version: + //tc.setCaretPosition(oldCarrot + insertion.length() - 1); + // sun vm version: + tc.setCaretPosition(oldCarrot + insertion.length()); + event.consume(); + } + break; + } }); + */ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); if ((PdeBase.platform == PdeBase.MACOSX) || @@ -523,6 +574,30 @@ public class PdeEditor extends Panel { sketchFile.getParent() + File.separator + "data"; //editor.sketchFile.getParent() + File.separator + "data"; +/* +this needs to be reworked. there are three essential parts + +(0. if not java, then use another 'engine'.. i.e. python) + +1. do the p5 language preprocessing + -> this creates a working .java file in a specific location + better yet, just takes a chunk of java code and returns a new/better string + editor can take care of saving this to a file location + +2. compile the code from that location + -| catching errors along the way + -| currently done with kjc, but would be nice to use jikes + -> placing it in a ready classpath, or .. ? + +3. run the code + needs to communicate location for window + and maybe setup presentation space as well + -> currently done internally + -> would be nice to use external (at least on non-os9) + +afterwards, some of these steps need a cleanup function +*/ + engine = new KjcEngine(this, program, buildPath, dataPath); //engine.start(); //engine.start(presenting ? presentLocation : appletLocation); diff --git a/app/PdeEditorConsole.java b/app/PdeEditorConsole.java index 5ce23d660..587e53bee 100644 --- a/app/PdeEditorConsole.java +++ b/app/PdeEditorConsole.java @@ -72,6 +72,15 @@ public class PdeEditorConsole extends Component { lineCount = PdeBase.getInteger("editor.console.lines", 6); + maxLineCount = 1000; + lines = new String[maxLineCount]; + isError = new boolean[maxLineCount]; + for (int i = 0; i < maxLineCount; i++) { + lines[i] = ""; + isError[i] = false; + } + firstLine = 0; + if (systemOut == null) { systemOut = System.out; systemErr = System.err; @@ -105,19 +114,12 @@ public class PdeEditorConsole extends Component { consoleErr = new PrintStream(new PdeEditorConsoleStream(this, true, stderrFile)); + /* System.setOut(consoleOut); System.setErr(consoleErr); + */ } - maxLineCount = 1000; - lines = new String[maxLineCount]; - isError = new boolean[maxLineCount]; - for (int i = 0; i < maxLineCount; i++) { - lines[i] = ""; - isError[i] = false; - } - firstLine = 0; - addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { int x = e.getX(); @@ -140,7 +142,7 @@ public class PdeEditorConsole extends Component { public void update() { - System.out.println("PdeEditorConsole.update"); + //System.out.println("PdeEditorConsole.update"); Graphics g = this.getGraphics(); if (g != null) paint(g); } @@ -150,6 +152,8 @@ public class PdeEditorConsole extends Component { } public void paint(Graphics screen) { + if (screen == null) return; + //systemOut.println("paint()"); if (bgColor == null) { diff --git a/app/PdeEditorListener.java b/app/PdeEditorListener.java index 067602539..ca04666d0 100644 --- a/app/PdeEditorListener.java +++ b/app/PdeEditorListener.java @@ -1,10 +1,14 @@ import java.awt.*; import java.awt.event.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.event.*; -public class PdeEditorListener extends KeyAdapter implements FocusListener { - static final String spaces = " "; - String newline = System.getProperty("line.separator"); + +public class PdeEditorListener extends KeyAdapter /*implements FocusListener*/ { + static final String spaces = " "; + //String newline = System.getProperty("line.separator"); PdeEditor editor; @@ -14,12 +18,13 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { boolean autoIndent; - boolean balanceParens; - boolean balancing = false; + // boolean balanceParens; + // boolean balancing = false; - boolean fakeArrowKeys; + //boolean fakeArrowKeys; - TextArea tc; + //TextArea tc; + //JTextPane tc; int selectionStart, selectionEnd; int position; @@ -27,13 +32,15 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { public PdeEditorListener(PdeEditor editor) { this.editor = editor; + //System.out.println("initing PdeEditorListener " + editor); + expandTabs = PdeBase.getBoolean("editor.expand_tabs", true); tabSize = PdeBase.getInteger("editor.tab_size", 2); tabString = spaces.substring(0, tabSize); autoIndent = PdeBase.getBoolean("editor.auto_indent", true); - balanceParens = PdeBase.getBoolean("editor.balance_parens", false); - fakeArrowKeys = PdeBase.getBoolean("editor.fake_arrow_keys", - PdeBase.platform == PdeBase.MACOSX); + // balanceParens = PdeBase.getBoolean("editor.balance_parens", false); + //fakeArrowKeys = PdeBase.getBoolean("editor.fake_arrow_keys", + // PdeBase.platform == PdeBase.MACOSX); } @@ -41,10 +48,18 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { // don't do things if the textarea isn't editable if (editor.externalEditor) return; + //System.out.println("blah blah"); + //System.out.println("source of event is " + event.getSource()); + // only works with TextArea, because it needs 'insert' //TextComponent tc = (TextComponent) event.getSource(); - tc = (TextArea) event.getSource(); - deselect(); + //tc = (TextArea) event.getSource(); + + JTextPane tc = (JTextPane) event.getSource(); + // getSource() returns PdeEditorTextPane, which is a JTextPane + //tc = editor.textarea; + + //deselect(); // this is for paren balancing char c = event.getKeyChar(); int code = event.getKeyCode(); //System.out.println(event); @@ -57,6 +72,7 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { } } +/* if (fakeArrowKeys && (c == 65535) && (code == KeyEvent.VK_LEFT || code == KeyEvent.VK_RIGHT || code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN)) { @@ -152,10 +168,12 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { tc.setCaretPosition(p); break; } - } + } +*/ //System.err.println((int)c); switch ((int) c) { +/* case ')': if (balanceParens) { position = tc.getCaretPosition() + 1; @@ -193,14 +211,16 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { } } break; +*/ case 9: // expand tabs if (expandTabs) { //System.out.println("start = " + tc.getSelectionStart()); //System.out.println("end = " + tc.getSelectionEnd()); //System.out.println("pos = " + tc.getCaretPosition()); - tc.replaceRange(tabString, tc.getSelectionStart(), - tc.getSelectionEnd()); + // tc.replaceRange(tabString, tc.getSelectionStart(), + // tc.getSelectionEnd()); + tc.replaceSelection(tabString); event.consume(); } break; @@ -209,48 +229,104 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { case 13: if (autoIndent) { //System.err.println("auto indenting"); + + //System.out.println("caret, sel = " + tc.getCaretPosition() + ", " + + // tc.getSelectionStart()); + char contents[] = tc.getText().toCharArray(); + // for (int j = 0; j < Math.min(contents.length, 200); j++) { + // System.out.println(j + " " + ((char)contents[j]) + " " + + // ((int)contents[j]) + " "); + // } + // System.out.println(); + + // this is the position of the caret, if the textarea + // only used a single kind of line ending + int origIndex = tc.getCaretPosition() - 1; + + //for (int i = 0; i < contents.length-1; i++) { + //if ((contents[i] == 13) && (contents[i+1] == 10)) offset++; + //} + + // walk through the array to the current caret position, + // and count how many weirdo windows line endings there are, + // which would be throwing off the caret position number + int offset = 0; + int realIndex = origIndex; + for (int i = 0; i < realIndex-1; i++) { + if ((contents[i] == 13) && (contents[i+1] == 10)) { + offset++; + realIndex++; + } + } + // back up until \r \r\n or \n.. @#($* cross platform - //index = contents.length-1; - int index = tc.getCaretPosition() - 1; + + //System.out.println(origIndex + " offset = " + offset); + origIndex += offset; // ARGH!#(* WINDOWS#@($* + + // if hitting enter on a line that is followed by spaces + // or blank lines, it seems that the caret position will be + // just after the newline + //if (PdeBase.platform == PdeBase.WINDOWS) { + //if (contents[origIndex] == 13) origIndex--; + //} + + int index = origIndex; int spaceCount = 0; boolean finished = false; while ((index != -1) && (!finished)) { - if ((contents[index] == '\r') || - (contents[index] == '\n')) { + if ((contents[index] == 10) || + (contents[index] == 13)) { finished = true; + index++; // maybe ? + // } else { + // spaceCount = (contents[index] == ' ') ? + // (spaceCount + 1) : 0; } else { - spaceCount = (contents[index] == ' ') ? - (spaceCount + 1) : 0; + //System.out.println("'" + (char)contents[index] + "'"); + index--; // new } - index--; } + //System.out.println("index is " + index); + while ((index < contents.length) && (index >= 0) && + (contents[index++] == ' ')) { + spaceCount++; + } + //System.out.println("spaceCount is " + spaceCount); // !@#$@#$ MS VM doesn't move the caret position to the // end of an insertion after it happens, even though sun does - String insertion = newline + spaces.substring(0, spaceCount); - int oldCarrot = tc.getSelectionStart(); - tc.replaceRange(insertion, oldCarrot, tc.getSelectionEnd()); + //String insertion = newline + spaces.substring(0, spaceCount); + + // seems that \r is being inserted anyway + // so no need to insert the platform's line separator + String insertion = "\n" + spaces.substring(0, spaceCount); + // int oldCarrot = tc.getSelectionStart(); + // tc.replaceRange(insertion, oldCarrot, tc.getSelectionEnd()); + // System.out.println("replacing with '" + insertion + "'"); + tc.replaceSelection(insertion); // microsoft vm version: //tc.setCaretPosition(oldCarrot + insertion.length() - 1); // sun vm version: - tc.setCaretPosition(oldCarrot + insertion.length()); + // tc.setCaretPosition(oldCarrot + insertion.length()); event.consume(); } break; - case 1: tc.selectAll(); break; // control a for select all + //case 1: tc.selectAll(); break; // control a for select all } } - + /* + // for balancing parens protected void deselect() { - if (!balancing || (tc == null)) return; + //if (!balancing || (tc == null)) return; // bounce back, otherwise will write over stuff if ((selectionStart == tc.getSelectionStart()) && (selectionEnd == tc.getSelectionEnd())) tc.setCaretPosition(position); - balancing = false; + //balancing = false; } @@ -260,4 +336,5 @@ public class PdeEditorListener extends KeyAdapter implements FocusListener { public void focusLost(FocusEvent event) { deselect(); } + */ } diff --git a/app/PdeEditorTextPane.java b/app/PdeEditorTextPane.java index b134ef97a..037ac938e 100644 --- a/app/PdeEditorTextPane.java +++ b/app/PdeEditorTextPane.java @@ -33,7 +33,7 @@ import java.util.*; //public class PdeEditorTextPane extends JPanel { public class PdeEditorTextPane extends JTextPane { - protected JTextPane textPane; + // MAYBE? protected JTextPane textPane; // styled document that is the model for the textPane public HighLightedDocument document; // pdebase needs it for undo @@ -65,7 +65,7 @@ public class PdeEditorTextPane extends JTextPane { //textPane = new JTextPane(document); setStyledDocument(document); - textPane = this; + // MAYBE? textPane = this; //setDoubleBuffered(true); @@ -110,7 +110,9 @@ public class PdeEditorTextPane extends JTextPane { // Start the thread that does the coloring colorer = new Colorer(); - colorer.start(); + if (PdeBase.getBoolean("editor.syntax_coloring", false)) { + colorer.start(); + } // Set up the hash table that contains the styles. //initStyles(); diff --git a/todo.txt b/todo.txt index c3e84672d..29fd714db 100644 --- a/todo.txt +++ b/todo.txt @@ -18,46 +18,63 @@ rect(100, height/2, thick, height/2); X re-implement sketchModified yet again (using keylistener) X set font on textarea in case things break X need examples to work for submenus (casey's got too many) +X why is javax.comm included a zillion times in exported .java file? +X fix issues with new swing-based text area +X auto indent on next line no longer works +X tabs no longer convert to 2 spaces +o balance parens is no longer available + +_ lots of problems with the console [maybe this needs to be a textarea?] +_ long lines seem to be trouble +_ also printing of objects, esp when null, in jdk 14 +_ exception when trying to write to stdout + +_ problem with axel's strings example [might be related to long lines] + +_ should java 1.3 classes be included in the imports +_ but not for exported applets? (might create some confusion) + +_ support 'classes' folder, through the use of a classloader +_ all .jar files etc are added from this folder automatically _ remove .class files on save as [dimitre] When I am working in a project and I save it with another name, all the old files are copyied to new directory, and some of the old unused .class files and images remains inside new project JAR files. -_ pmouseX should be set at the end of loop(), not on mouse movement - _ use date in the sketch name sketch_021104 _ with a _2 if needed or '021104a' '021104b' etc _ when using save as, allow to remove the old (numbered) sketch _ method of collapsing history for useful versions _ archive associated files as well.. data/etc -_ exception when trying to write to stdout + _ set frame title of launched window to the name of the sketch bagel +_ pmouseX should be set at the end of loop(), not on mouse movement _ font smoothing (unless hint SMOOTH_IMAGES enabled) is broken _ images don't load during setup() -_ finish fill mode of flat circle function -_ make into oval function _ 'image' is too generic a variable to have inside BApplet _ check for others that shouldn't be used (pixels? width? height?) _ or have a way to syntax color them _ make bagel usable on its own w/o applet _ but retain functionality, ie. image i/o +_ finish fill mode of flat circle function +_ make into oval function pde _ "color.jpg" or "int.jpg" causes trouble _ "http://acg.media.mit.edu" doesn't work because of // _ subst Image -> BImage, Font -> BFont -_ auto indent on next line no longer works -_ tabs no longer convert to 2 spaces -_ balance parens is no longer available +_ seems that file i/o may be picking up lots of extra \r +_ perhaps when doing setText, it's goobering things up _ better default size than 300x300 when starting up first time _ better message for PortInUseException (full explanation) _ split KjcEngine into three parts +_ how to communicate with other applet/jre when it's been launched _ move build directory to root in cvs (on server) _ and update scripts accordingly _ When renaming a sketch, select the text in the field, @@ -71,6 +88,7 @@ _ lockup/freezes (mKoser and zeitgeist) _ jre icon not appearing in the systray macosx +_ check to see if swing is working properly _ put mac rxtx inside the p5 folder (hide it?) _ include more strongly worded message about rxtx _ bug report from the site