/** * Called when a user processing input characters and select candidates from input method. * * @param text Text from InputMethodEvent. * @param commited_count Numbers of committed characters in text. */ public void processCompositionText(AttributedCharacterIterator text, int committed_count) { int layoutCaretPosition = initialCaretPosition + committed_count; CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter(); compositionPainter.setComposedTextLayout( getTextLayout(text, committed_count), layoutCaretPosition); int textLength = text.getEndIndex() - text.getBeginIndex() - committed_count; StringBuffer unCommitedStringBuf = new StringBuffer(textLength); char c; for (c = text.setIndex(committed_count); c != AttributedCharacterIterator.DONE && textLength > 0; c = text.next(), --textLength) { unCommitedStringBuf.append(c); } String unCommittedString = unCommitedStringBuf.toString(); try { if (canRemovePreviousInput(committed_count)) { textArea.getDocument().remove(layoutCaretPosition, prevComposeString.length()); } textArea.getDocument().insertString(layoutCaretPosition, unCommittedString, null); if (committed_count > 0) { initialCaretPosition = initialCaretPosition + committed_count; } prevComposeString = unCommittedString; prevCommittedCount = committed_count; } catch (BadLocationException e) { e.printStackTrace(); } }
/** * Fill color to erase characters drawn by original TextAreaPainter. * * @param fillColor fill color to erase characters drawn by original TextAreaPainter method. * @param x x-coordinate where to fill. * @param y y-coordinate where to fill. */ private void refillComposedArea(Color fillColor, int x, int y) { Graphics gfx = textArea.getPainter().getGraphics(); gfx.setColor(fillColor); FontMetrics fm = textArea.getPainter().getFontMetrics(); int newY = y - (fm.getHeight() - CompositionTextManager.COMPOSING_UNDERBAR_HEIGHT); int paintHeight = fm.getHeight(); int paintWidth = (int) composedTextLayout.getBounds().getWidth(); gfx.fillRect(x, newY, paintWidth, paintHeight); }
private TextLayout getTextLayout(AttributedCharacterIterator text, int committed_count) { AttributedString composed = new AttributedString(text, committed_count, text.getEndIndex()); Font font = textArea.getPainter().getFont(); FontRenderContext context = ((Graphics2D) (textArea.getPainter().getGraphics())).getFontRenderContext(); composed.addAttribute(TextAttribute.FONT, font); TextLayout layout = new TextLayout(composed.getIterator(), context); return layout; }
/** Insert full width space */ public void insertFullWidthSpace() { initialCaretPosition = textArea.getCaretPosition(); int layoutCaretPosition = initialCaretPosition; try { textArea.getDocument().insertString(layoutCaretPosition, "\u3000", null); } catch (BadLocationException e) { e.printStackTrace(); } }
private Point getCaretLocation() { Point loc = new Point(); TextAreaPainter painter = textArea.getPainter(); FontMetrics fm = painter.getFontMetrics(); int offsetY = fm.getHeight() - COMPOSING_UNDERBAR_HEIGHT; int lineIndex = textArea.getCaretLine(); loc.y = lineIndex * fm.getHeight() + offsetY; int offsetX = textArea.getCaretPosition() - textArea.getLineStartOffset(lineIndex); loc.x = textArea.offsetToX(lineIndex, offsetX); return loc; }
/** * Show the code window and all its component parts * * @param b */ public void setVisible(boolean b) { // System.out.println("kCodeWindow opaque >> editFrame="+editFrame.isOpaque()+ " // buttonFrame="+buttonFrame.isOpaque()+" triangleFrame="+triangleFrame.isOpaque()); editFrame.setVisible(b); buttonFrame.setVisible(b); triangleFrame.setVisible(b); ((DrawingArea) desktop).fireCodeWindowEvent(); if (b) textarea.requestFocus(); }
private void removeNotCommittedText(AttributedCharacterIterator text) { if (prevComposeString.length() == 0) { return; } try { textArea.getDocument().remove(initialCaretPosition, prevComposeString.length()); } catch (BadLocationException e) { e.printStackTrace(); } }
/** * Called when a user fixed text from input method or delete all composition text. This method * resets CompositionTextPainter. * * @param text Text from InputMethodEvent. * @param commited_count Numbers of committed characters in text. */ public void endCompositionText(AttributedCharacterIterator text, int committed_count) { /* * If there are no committed characters, remove it all from textarea. * This case will happen if a user delete all composing characters by backspace or delete key. * If it does, these previous characters are needed to be deleted. */ if (committed_count == 0) { removeNotCommittedText(text); } CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter(); compositionPainter.invalidateComposedTextLayout(initialCaretPosition + committed_count); prevComposeString = ""; isInputProcess = false; }
public EditorLineStatus(JEditTextArea textarea) { this.textarea = textarea; textarea.editorLineStatus = this; background = Theme.getColor("linestatus.bgcolor"); font = Theme.getFont("linestatus.font"); foreground = Theme.getColor("linestatus.color"); high = Theme.getInteger("linestatus.height"); if (Base.isMacOS()) { resize = Base.getThemeImage("resize.gif", this); } // linestatus.bgcolor = #000000 // linestatus.font = SansSerif,plain,10 // linestatus.color = #FFFFFF }
/** @param buttonPanel */ protected void installFocusHandlers(JPanel buttonPanel) { // disable buttons when this "frame" is defocused FocusListener focusListener = new FocusListener() { public void focusGained(FocusEvent e) { moveButton.setEnabled(true); closeButton.setEnabled(true); } public void focusLost(FocusEvent e) { moveButton.setEnabled(false); closeButton.setEnabled(false); } }; textarea.addFocusListener(focusListener); // have to put the focus listener on every component else it doesn't work every time buttonPanel.addFocusListener(focusListener); moveButton.addFocusListener(focusListener); closeButton.addFocusListener(focusListener); }
/** * Called when a user begins input from input method. This method initializes text manager. * * @param text Text from InputMethodEvent. * @param commited_count Numbers of committed characters in text. */ public void beginCompositionText(AttributedCharacterIterator text, int committed_count) { isInputProcess = true; prevComposeString = ""; initialCaretPosition = textArea.getCaretPosition(); processCompositionText(text, committed_count); }
/** * Constructor: The one we're working on right now. * * @param id * @param label * @param desktop */ public kCodeWindow(String id, String label, JDesktopPane desktop) { this.id = id; this.desktop = desktop; // make the editor portions TextAreaDefaults editareaSettings = new PdeTextAreaDefaults(); editareaSettings.rows = TEXTAREA_DEFAULT_ROWS; editareaSettings.cols = TEXTAREA_DEFAULT_COLS; textarea = new JEditTextArea(editareaSettings); textarea.getDocument().setTokenMarker(Editor.pdeTokenMarker); textarea.setEventsEnabled( false); // suppress JEditTextArea events (not that anyone is listening to it) textarea.setEditable(true); textarea.setHorizontalOffset(TEXTAREA_HORIZ_OFFSET); textarea.getPainter().setLineHighlightEnabled(false); // else looks funny textarea.getPainter().setBackground(kConstants.CODE_WINDOW_COLOR); setShortcutKeystrokes(); JScrollPane scrollPane = new JScrollPane(textarea); scrollPane.setBorder(null); // scrollPane.setOpaque(true); editFrame = new JInternalFrame(label, true, false, false, false); editFrame.setContentPane(textarea); editFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); editFrame.setSize(editFrame_DEFAULT_WIDTH, editFrame_DEFAULT_HEIGHT); editFrame.setBorder(null); editFrame.setOpaque(true); // make the triangle triangleFrame = new JInternalFrame("", false, false, false, false); triangleFrame.setOpaque(false); triangleFrame .getRootPane() .setBackground(new Color(0, 0, 0, 0)); // needs this to actually do the trick triangleFrame.setContentPane( new Triangle("SE", 0, TRIANGLE_BASE, TRIANGLE_DEFAULT_HEIGHT, TRIANGLE_BASE)); triangleFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); triangleFrame.setSize(TRIANGLE_BASE, TRIANGLE_DEFAULT_HEIGHT); triangleFrame.setBorder(null); // remove the ability to move the triangle iframe MouseMotionListener[] actions = (MouseMotionListener[]) triangleFrame.getListeners(MouseMotionListener.class); for (int i = 0; i < actions.length; i++) triangleFrame.removeMouseMotionListener(actions[i]); // make the buttons moveButton = new JButton(Base.getImageIcon("codewindow-activ-move.gif", desktop)); moveButton.setDisabledIcon(Base.getImageIcon("codewindow-inact-move.gif", desktop)); moveButton.setVisible(true); moveButton.setBorder(null); moveButton.setOpaque(false); moveButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); closeButton = new JButton(Base.getImageIcon("codewindow-activ-close.gif", desktop)); closeButton.setDisabledIcon(Base.getImageIcon("codewindow-inact-close.gif", desktop)); closeButton.setVisible(true); closeButton.setBorder(null); closeButton.setOpaque(false); closeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 0)); buttonPanel.setBorder(null); buttonPanel.setOpaque(false); buttonPanel.add(moveButton); buttonPanel.add(closeButton); buttonFrame = new JInternalFrame("", false, false, false, false); buttonFrame.setContentPane(buttonPanel); buttonFrame.setOpaque(false); buttonFrame.getRootPane().setBackground(new Color(0, 0, 0, 0)); buttonFrame.setSize(BUTTON_ICON_WIDTH * 2 + BUTTON_GAP, BUTTON_ICON_HEIGHT); buttonFrame.setBorder(null); // myriad event handling installFocusHandlers(buttonPanel); // hide code window when escape key is hit textarea.addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) setVisible(false); } }); // add dragging function of the move button, // reset the triangle after mouse release, and shift the editFrame // along with the mouse when the user is moving the window mxMouseControl moveListener = createMoveListener(); moveButton.addMouseListener(moveListener); moveButton.addMouseMotionListener(moveListener); closeButton.addMouseListener(createCloseListener()); // listens to resizing of editFrame and adjusts the position of the // buttons and the shape of the triangle accordingly editFrame.addComponentListener(createResizeListener()); // when code windows are on top of each other, layers them correctly // such that when the user clicks on any part of a code window // all three component internal frames are brought to the top // so they appear "focused" also InternalFrameListener iframeListener = new InternalFrameAdapter() { public void internalFrameActivated(InternalFrameEvent e) { moveToFrontLayer(); } public void internalFrameDeactivated(InternalFrameEvent e) { moveToBackLayer(); } }; editFrame.addInternalFrameListener(iframeListener); buttonFrame.addInternalFrameListener(iframeListener); triangleFrame.addInternalFrameListener(iframeListener); // add everything to desktop desktop.add(editFrame); desktop.add(buttonFrame); desktop.add(triangleFrame); moveToBackLayer(); }
public int getInsertPositionOffset() { return textArea.getCaretPosition() * -1; }
public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex) { int length = endIndex - beginIndex; String textAreaString = textArea.getText(beginIndex, length); return new AttributedString(textAreaString).getIterator(); }
private Rectangle getCaretRectangle(int x, int y) { TextAreaPainter painter = textArea.getPainter(); Point origin = painter.getLocationOnScreen(); int height = painter.getFontMetrics().getHeight(); return new Rectangle(origin.x + x, origin.y + y, 0, height); }
/** To support drag-drop of strings, and cut-copy-paste actions in the code window text editor. */ protected void setShortcutKeystrokes() { final int SHORTCUT_KEY_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); InputMap imap = textarea.getInputMap(); imap.put( KeyStroke.getKeyStroke('X', SHORTCUT_KEY_MASK), TransferHandler.getCutAction().getValue(Action.NAME)); imap.put( KeyStroke.getKeyStroke('C', SHORTCUT_KEY_MASK), TransferHandler.getCopyAction().getValue(Action.NAME)); imap.put( KeyStroke.getKeyStroke('V', SHORTCUT_KEY_MASK), TransferHandler.getPasteAction().getValue(Action.NAME)); imap.put(KeyStroke.getKeyStroke('A', SHORTCUT_KEY_MASK), "selectAll"); imap.put(KeyStroke.getKeyStroke('/', SHORTCUT_KEY_MASK), "commentUncomment"); imap.put(KeyStroke.getKeyStroke(']', SHORTCUT_KEY_MASK), "increaseIndent"); imap.put(KeyStroke.getKeyStroke('[', SHORTCUT_KEY_MASK), "decreaseIndent"); ActionMap amap = textarea.getActionMap(); amap.put( TransferHandler.getCutAction().getValue(Action.NAME), new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> cut "+e.getSource()); ((JEditTextArea) e.getSource()).cut(); } }); amap.put( TransferHandler.getCopyAction().getValue(Action.NAME), new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> copy "+e.getSource()); ((JEditTextArea) e.getSource()).copy(); } }); amap.put( TransferHandler.getPasteAction().getValue(Action.NAME), new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> paste "+e.getSource()); ((JEditTextArea) e.getSource()).paste(); } }); amap.put( "selectAll", new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> select all "+e.getSource()); ((JEditTextArea) e.getSource()).selectAll(); } }); amap.put( "commentUncomment", new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> comment // uncomment"+e.getSource()); handleCommentUncomment(); } }); amap.put( "increaseIndent", new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> increaseIndent"+e.getSource()); handleIndentOutdent(true); } }); amap.put( "decreaseIndent", new AbstractAction() { public void actionPerformed(ActionEvent e) { // System.out.println("kCodeWindow ActionMap >> decreaseIndent"+e.getSource()); handleIndentOutdent(false); } }); }
/** * @see processing.app.Editor#handleCommentUncomment * @author fry */ public void handleCommentUncomment() { // TODO startCompoundEdit(); int startLine = textarea.getSelectionStartLine(); int stopLine = textarea.getSelectionStopLine(); int lastLineStart = textarea.getLineStartOffset(stopLine); int selectionStop = textarea.getSelectionStop(); // If the selection ends at the beginning of the last line, // then don't (un)comment that line. if (selectionStop == lastLineStart) { // Though if there's no selection, don't do that if (textarea.isSelectionActive()) { stopLine--; } } // If the text is empty, ignore the user. // Also ensure that all lines are commented (not just the first) // when determining whether to comment or uncomment. int length = textarea.getDocumentLength(); boolean commented = true; for (int i = startLine; commented && (i <= stopLine); i++) { int pos = textarea.getLineStartOffset(i); if (pos + 2 > length) { commented = false; } else { // Check the first two characters to see if it's already a comment. String begin = textarea.getText(pos, 2); // System.out.println("begin is '" + begin + "'"); commented = begin.equals("//"); } } for (int line = startLine; line <= stopLine; line++) { int location = textarea.getLineStartOffset(line); if (commented) { // remove a comment textarea.select(location, location + 2); if (textarea.getSelectedText().equals("//")) { textarea.setSelectedText(""); // pseudo-code: // find open code windows // find localLocation // insert/remove // update all codeblocks after } } else { // add a comment textarea.select(location, location); textarea.setSelectedText("//"); } } // Subtract one from the end, otherwise selects past the current line. // (Which causes subsequent calls to keep expanding the selection) textarea.select( textarea.getLineStartOffset(startLine), textarea.getLineStopOffset(stopLine) - 1); // stopCompoundEdit(); }
/** * @see processing.app.Editor#handleIndentOutdent * @author fry */ public void handleIndentOutdent(boolean indent) { int tabSize = Preferences.getInteger("editor.tabs.size"); String tabString = " ".substring(0, tabSize); // TODO startCompoundEdit(); int startLine = textarea.getSelectionStartLine(); int stopLine = textarea.getSelectionStopLine(); // If the selection ends at the beginning of the last line, // then don't (un)comment that line. int lastLineStart = textarea.getLineStartOffset(stopLine); int selectionStop = textarea.getSelectionStop(); if (selectionStop == lastLineStart) { // Though if there's no selection, don't do that if (textarea.isSelectionActive()) { stopLine--; } } for (int line = startLine; line <= stopLine; line++) { int location = textarea.getLineStartOffset(line); if (indent) { textarea.select(location, location); textarea.setSelectedText(tabString); } else { // outdent textarea.select(location, location + tabSize); // Don't eat code if it's not indented if (textarea.getSelectedText().equals(tabString)) { textarea.setSelectedText(""); } } } // Subtract one from the end, otherwise selects past the current line. // (Which causes subsequent calls to keep expanding the selection) textarea.select( textarea.getLineStartOffset(startLine), textarea.getLineStopOffset(stopLine) - 1); // stopCompoundEdit(); }
/** Handles KeyEvents for TextArea (code completion begins from here). */ public void processKeyEvent(KeyEvent evt) { if (evt.getKeyCode() == KeyEvent.VK_ESCAPE) { if (suggestion != null) { if (suggestion.isVisible()) { Messages.log("esc key"); hideSuggestion(); evt.consume(); return; } } } else if (evt.getKeyCode() == KeyEvent.VK_ENTER && evt.getID() == KeyEvent.KEY_PRESSED) { if (suggestion != null && suggestion.isVisible() && suggestion.insertSelection(CompletionPanel.KEYBOARD_COMPLETION)) { evt.consume(); // Still try to show suggestions after inserting if it's // the case of overloaded methods. See #2755 if (suggestion.isVisible()) { prepareSuggestions(evt); } return; } } if (evt.getID() == KeyEvent.KEY_PRESSED) { switch (evt.getKeyCode()) { case KeyEvent.VK_DOWN: if (suggestion != null) if (suggestion.isVisible()) { // log("KeyDown"); suggestion.moveDown(); return; } break; case KeyEvent.VK_UP: if (suggestion != null) if (suggestion.isVisible()) { // log("KeyUp"); suggestion.moveUp(); return; } break; case KeyEvent.VK_BACK_SPACE: Messages.log("BK Key"); break; case KeyEvent.VK_SPACE: if (suggestion != null) { if (suggestion.isVisible()) { Messages.log("Space bar, hide completion list"); suggestion.setInvisible(); } } break; } } super.processKeyEvent(evt); // code completion disabled if Java tabs present if (!editor.hasJavaTabs()) { if (evt.getID() == KeyEvent.KEY_TYPED) { processCompletionKeys(evt); } else if (!Platform.isMacOS() && evt.getID() == KeyEvent.KEY_RELEASED) { processCompletionKeys(evt); } else if (Platform.isMacOS() && evt.getID() == KeyEvent.KEY_RELEASED) { processControlSpace(evt); } } }