@Override protected Transferable createTransferable(JComponent c) { JTextPane aTextPane = (JTextPane) c; HTMLEditorKit kit = ((HTMLEditorKit) aTextPane.getEditorKit()); StyledDocument sdoc = aTextPane.getStyledDocument(); int sel_start = aTextPane.getSelectionStart(); int sel_end = aTextPane.getSelectionEnd(); int i = sel_start; StringBuilder output = new StringBuilder(); while (i < sel_end) { Element e = sdoc.getCharacterElement(i); Object nameAttr = e.getAttributes().getAttribute(StyleConstants.NameAttribute); int start = e.getStartOffset(), end = e.getEndOffset(); if (nameAttr == HTML.Tag.BR) { output.append("\n"); } else if (nameAttr == HTML.Tag.CONTENT) { if (start < sel_start) { start = sel_start; } if (end > sel_end) { end = sel_end; } try { String str = sdoc.getText(start, end - start); output.append(str); } catch (BadLocationException ble) { Debug.error(me + "Copy-paste problem!\n%s", ble.getMessage()); } } i = end; } return new StringSelection(output.toString()); }
private void addStyledText(String text, Style style) { try { doc.insertString(doc.getLength(), text, style); } catch (BadLocationException ble) { ble.printStackTrace(); } }
private void initializeStyles() { errorStyle = doc.addStyle( "errorStyle", StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE)); errorStyleRed = doc.addStyle("errorStyleRed", errorStyle); StyleConstants.setForeground(errorStyleRed, Color.RED); errorStyleMono = doc.addStyle("errorStyleMono", errorStyle); StyleConstants.setFontFamily(errorStyleMono, "Monospaced"); }
private void loadStyles(StyledDocument doc) { Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE); StyleConstants.setFontFamily(def, "Courier New"); // Add normal style Style normal = doc.addStyle("normal", def); StyleConstants.setForeground(def, Color.LIGHT_GRAY); // Add highlighted style from normal Style red = doc.addStyle("red", normal); StyleConstants.setForeground(red, Color.RED); }
private void handleDecreaseIndent(int line, Element elem, StyledDocument doc) throws BadLocationException { int start = elem.getStartOffset(); int end = elem.getEndOffset() - 1; doc.getText(start, end - start, segLine); int i = segLine.offset; end = i + segLine.count; if (end > i) { String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, end - start); int toRemove = indentationLogic.checkDedent(leadingWS, line + 1); doc.remove(start, toRemove); } }
private void setOutput() { String[] styles = new String[traceLines.length]; Pattern p1 = Pattern.compile("uk.co.essarsoftware.par.", Pattern.LITERAL); for (int i = 0; i < styles.length; i++) { styles[i] = (p1.matcher(traceLines[i]).find() ? "red" : "normal"); } StyledDocument doc = getStyledDocument(); try { for (int i = 0; i < traceLines.length; i++) { doc.insertString(doc.getLength(), traceLines[i] + "\n", doc.getStyle(styles[i])); } } catch (BadLocationException ble) { setText("Unexpected exception loading stack trace"); } }
@Override public void mouseClicked(MouseEvent me) { Element el = doc.getCharacterElement(viewToModel(me.getPoint())); if (el == null) return; AttributeSet as = el.getAttributes(); if (as.isDefined("ip")) { String ip = (String) as.getAttribute("ip"); ScriptException se = (ScriptException) as.getAttribute("exception"); Node node = net.getAtIP(ip); if (node == null) { Utility.displayError("Error", "Computer does not exist"); return; } String errorString = "--ERROR--\n" + "Error at line number " + se.getLineNumber() + " and column number " + se.getColumnNumber() + "\n" + se.getMessage(); new ScriptDialog( parentFrame, str -> { if (str != null) { node.setScript(str); } }, node.getScript(), errorString) .setVisible(true); } }
@Override public void mouseMoved(MouseEvent me) { Element el = doc.getCharacterElement(viewToModel(me.getPoint())); if (el == null) return; AttributeSet as = el.getAttributes(); if (as.isDefined("ip")) { setCursor(handCursor); } else { setCursor(defaultCursor); } }
public void actionPerformed(JTextComponent text) { indentationLogic = ((EditorPane) text).getIndentationLogic(); StyledDocument doc = (StyledDocument) text.getDocument(); Element map = doc.getDefaultRootElement(); Caret c = text.getCaret(); int dot = c.getDot(); int mark = c.getMark(); int line1 = map.getElementIndex(dot); if (dot != mark) { int line2 = map.getElementIndex(mark); int begin = Math.min(line1, line2); int end = Math.max(line1, line2); Element elem; try { for (line1 = begin; line1 < end; line1++) { elem = map.getElement(line1); handleDecreaseIndent(line1, elem, doc); } elem = map.getElement(end); int start = elem.getStartOffset(); if (Math.max(c.getDot(), c.getMark()) != start) { handleDecreaseIndent(end, elem, doc); } } catch (BadLocationException ble) { Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage()); UIManager.getLookAndFeel().provideErrorFeedback(text); } } else { Element elem = map.getElement(line1); try { handleDecreaseIndent(line1, elem, doc); } catch (BadLocationException ble) { Debug.error(me + "Problem while de-indenting line\n%s", ble.getMessage()); UIManager.getLookAndFeel().provideErrorFeedback(text); } } }
private void insertNewlineWithAutoIndent(JTextComponent text) { try { int caretPos = text.getCaretPosition(); StyledDocument doc = (StyledDocument) text.getDocument(); Element map = doc.getDefaultRootElement(); int lineNum = map.getElementIndex(caretPos); Element line = map.getElement(lineNum); int start = line.getStartOffset(); int end = line.getEndOffset() - 1; int len = end - start; String s = doc.getText(start, len); String leadingWS = PythonIndentation.getLeadingWhitespace(doc, start, caretPos - start); StringBuffer sb = new StringBuffer("\n"); sb.append(leadingWS); // TODO better control over automatic indentation indentationLogic.checkIndent(leadingWS, lineNum + 1); // If there is only whitespace between the caret and // the EOL, pressing Enter auto-indents the new line to // the same place as the previous line. int nonWhitespacePos = PythonIndentation.atEndOfLine(doc, caretPos, start, s, len); if (nonWhitespacePos == -1) { if (leadingWS.length() == len) { // If the line was nothing but whitespace, select it // so its contents get removed. text.setSelectionStart(start); } else { // Select the whitespace between the caret and the EOL // to remove it text.setSelectionStart(caretPos); } text.setSelectionEnd(end); text.replaceSelection(sb.toString()); // auto-indentation for python statements like if, while, for, try, // except, def, class and auto-deindentation for break, continue, // pass, return analyseDocument(doc, lineNum, indentationLogic); // auto-completion: add colon if it is obvious if (indentationLogic.shouldAddColon()) { doc.insertString(caretPos, ":", null); indentationLogic.setLastLineEndsWithColon(); } int lastLineChange = indentationLogic.shouldChangeLastLineIndentation(); int nextLineChange = indentationLogic.shouldChangeNextLineIndentation(); if (lastLineChange != 0) { Debug.log(5, "change line %d indentation by %d columns", lineNum + 1, lastLineChange); changeIndentation((DefaultStyledDocument) doc, lineNum, lastLineChange); // nextLineChange was determined based on indentation of last line before // the change nextLineChange += lastLineChange; } if (nextLineChange != 0) { Debug.log(5, "change line %d indentation by %d columns", lineNum + 2, nextLineChange); changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange); } } // If there is non-whitespace between the caret and the // EOL, pressing Enter takes that text to the next line // and auto-indents it to the same place as the last // line. Additional auto-indentation or dedentation for // specific python statements is only done for the next line. else { text.setCaretPosition(nonWhitespacePos); doc.insertString(nonWhitespacePos, sb.toString(), null); analyseDocument(doc, lineNum, indentationLogic); int nextLineChange = indentationLogic.shouldChangeNextLineIndentation(); if (nextLineChange != 0) { Debug.log(5, "change line %d indentation by %d columns", lineNum + 2, nextLineChange); changeIndentation((DefaultStyledDocument) doc, lineNum + 1, nextLineChange); } } } catch (BadLocationException ble) { text.replaceSelection("\n"); Debug.error(me + "Problem while inserting new line with auto-indent\n%s", ble.getMessage()); } }
public static void main() { // Main frame = new JFrame("Java Playground"); frame.setSize(640, 480); // Make sure the divider is properly resized frame.addComponentListener( new ComponentAdapter() { public void componentResized(ComponentEvent c) { splitter.setDividerLocation(.8); } }); // Make sure the JVM is reset on close frame.addWindowListener( new WindowAdapter() { public void windowClosed(WindowEvent w) { new FrameAction().kill(); } }); // Setting up the keybinding // Ctrl+k or Cmd+k -> compile bind(KeyEvent.VK_K); // Ctrl+e or Cmd+e -> console bind(KeyEvent.VK_E); // Save, New file, Open file, Print. // Currently UNUSED until I figure out how normal java files and playground files will // interface. bind(KeyEvent.VK_S); bind(KeyEvent.VK_N); bind(KeyEvent.VK_O); bind(KeyEvent.VK_P); // Binds the keys to the action defined in the FrameAction class. frame.getRootPane().getActionMap().put("console", new FrameAction()); // The main panel for typing code in. text = new JTextPane(); textScroll = new JScrollPane(text); textScroll.setBorder(null); textScroll.setPreferredSize(new Dimension(640, 480)); // Document with syntax highlighting. Currently unfinished. doc = text.getStyledDocument(); doc.addDocumentListener( new DocumentListener() { public void changedUpdate(DocumentEvent d) {} public void insertUpdate(DocumentEvent d) {} public void removeUpdate(DocumentEvent d) {} }); ((AbstractDocument) doc).setDocumentFilter(new NewLineFilter()); // The output log; a combination compiler warning/error/runtime error/output log. outputText = new JTextPane(); outputScroll = new JScrollPane(outputText); outputScroll.setBorder(null); // "Constant" for the error font error = new SimpleAttributeSet(); error.addAttribute(StyleConstants.CharacterConstants.Italic, Boolean.TRUE); error.addAttribute(StyleConstants.Foreground, Color.RED); // "Constant" for the warning message font warning = new SimpleAttributeSet(); warning.addAttribute(StyleConstants.CharacterConstants.Italic, Boolean.TRUE); warning.addAttribute(StyleConstants.Foreground, Color.PINK); // "Constant" for the debugger error font progErr = new SimpleAttributeSet(); progErr.addAttribute(StyleConstants.Foreground, Color.BLUE); // Print streams to redirect System.out and System.err. out = new TextOutputStream(outputText, null); err = new TextOutputStream(outputText, error); System.setOut(new PrintStream(out)); System.setErr(new PrintStream(err)); // Sets up the output log outputText.setEditable(false); outputScroll.setVisible(true); // File input/output setup chooser = new JFileChooser(); // Setting up miscellaneous stuff compiler = ToolProvider.getSystemJavaCompiler(); JVMrunning = false; redirectErr = null; redirectOut = null; redirectIn = null; // Sets up the splitter pane and opens the program up splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT, textScroll, outputScroll); consoleDisplayed = false; splitter.remove(outputScroll); // Initially hides terminal until it is needed splitter.setOneTouchExpandable(true); frame.add(splitter); frame.setVisible(true); // Sets the divider to the proper one, for debugging // splitter.setDividerLocation(.8); }
@Override public void actionPerformed(ActionEvent e) { licence_text = new String( "This program is free software: you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation, either version 3 of the License, or\n" + "(at your option) any later version.\n" + "\n" + "This program is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + "GNU General Public License for more details.\n" + "\n" + "You should have received a copy of the GNU General Public License\n" + "along with this program. If not, see <http://www.gnu.org/licenses/>.\n" + "\n\n\n"); try { InputStream ips = new FileInputStream(getClass().getResource("COPYING").getPath()); InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String line; while ((line = br.readLine()) != null) { licence_text += line + '\n'; } br.close(); } catch (Exception e1) { } Dimension dimension = new Dimension(600, 400); JDialog licence = new JDialog(memento, "Licence"); JTextPane text_pane = new JTextPane(); text_pane.setEditable(false); text_pane.setPreferredSize(dimension); text_pane.setSize(dimension); StyledDocument doc = text_pane.getStyledDocument(); Style justified = doc.addStyle( "justified", StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE)); StyleConstants.setAlignment(justified, StyleConstants.ALIGN_JUSTIFIED); try { doc.insertString(0, licence_text, justified); } catch (BadLocationException ble) { System.err.println("Couldn't insert initial text into text pane."); } Style logicalStyle = doc.getLogicalStyle(0); doc.setParagraphAttributes(0, licence_text.length(), justified, false); doc.setLogicalStyle(0, logicalStyle); JScrollPane paneScrollPane = new JScrollPane(text_pane); paneScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); paneScrollPane.setPreferredSize(dimension); paneScrollPane.setMinimumSize(dimension); JPanel pan = new JPanel(); LayoutManager layout = new BorderLayout(); pan.setLayout(layout); pan.add(new JScrollPane(paneScrollPane), BorderLayout.CENTER); JButton close = new JButton("Fermer"); close.addActionListener(new ButtonCloseActionListener(licence)); JPanel button_panel = new JPanel(); FlowLayout button_panel_layout = new FlowLayout(FlowLayout.RIGHT, 20, 20); button_panel.setLayout(button_panel_layout); button_panel.add(close); pan.add(button_panel, BorderLayout.SOUTH); licence.add(pan); licence.pack(); licence.setLocationRelativeTo(memento); licence.setVisible(true); }
/** Returns the border's color, or null if this is not a link. */ Color getBorderColor() { StyledDocument doc = (StyledDocument) getDocument(); return doc.getForeground(getAttributes()); }