📄 jexttextarea.java
字号:
setEditable(true); buffer = new StringBuffer((int) toLoad.length()); in = new InputStreamReader(new FileInputStream(toLoad), Jext.getProperty("editor.encoding", System.getProperty("file.encoding"))); } else { in = _in; if (bufferSize == 0) bufferSize = BUFFER_SIZE * 4; buffer = new StringBuffer(bufferSize); } char[] buf = new char[BUFFER_SIZE]; int len; int lineCount = 0; boolean CRLF = false; boolean CROnly = false; boolean lastWasCR = false; // we read the file till its end (amazing, hu ?) while ((len = in.read(buf, 0, buf.length)) != -1) { int lastLine = 0; for (int i = 0; i < len; i++) { switch(buf[i]) { // and we convert system's carriage return char into \n case '\r': if (lastWasCR) { CROnly = true; CRLF = false; } else lastWasCR = true; buffer.append(buf, lastLine, i - lastLine); buffer.append('\n'); lastLine = i + 1; break; case '\n': if (lastWasCR) { CROnly = false; CRLF = true; lastWasCR = false; lastLine = i + 1; } else { CROnly = false; CRLF = false; buffer.append(buf, lastLine, i - lastLine); buffer.append('\n'); lastLine = i + 1; } break; default: if (lastWasCR) { CROnly = true; CRLF = false; lastWasCR = false; } break; } } buffer.append(buf, lastLine, len - lastLine); } in.close(); in = null; //handle line end choice resetLineTerm(); if (Jext.getBooleanProperty("editor.line_end.preserve")) if(CROnly) setLineTerm("\r"); else if (CRLF) //then CRLF is true setLineTerm("\r\n"); else setLineTerm("\n"); storeOrigLineTerm(); //so we can see if it has been changed. lineTermSelector.setSelectedItem(getLineTermName()); getJextParent().setLineTerm(JextTextArea.this, lineTermSelector.getSelectedIndex()); //this updates the other TextArea if //the JextFrame is splitted if (buffer.length() != 0 && buffer.charAt(buffer.length() - 1) == '\n') buffer.setLength(buffer.length() - 1); // we clear the area document.remove(0, getLength()); // we put the text in it document.insertString(0, buffer.toString(), null); buffer = null; setCaretPosition(0); parent.setNew(this); // we add the file into the recent menu if (_in == null) { parent.setTextAreaName(this, getFileName(path)); if (addToRecentList) parent.saveRecent(path); currentFile = path; newf = false; modTime = getFile().lastModified(); } else { if (!web) currentFile = (new File(path)).getName(); else currentFile = path.substring(path.lastIndexOf('/') + 1); parent.setTextAreaName(this, currentFile); newf = true; setDirty(); parent.setChanged(this); _in.close(); _in = null; } setParentTitle(); // and we choose the most appropriate syntax colorization mode String low = path.toLowerCase(); String _mode; boolean modeSet = false; RE regexp; for (int i = Jext.modes.size() - 1; i >= 0; i--) { Mode modeClass = (Mode) Jext.modes.get(i); if (modeClass == null) continue; _mode = modeClass.getModeName(); if (_mode.equals("plain")) continue; try { regexp = new RE(Utilities.globToRE(Jext.getProperty("mode." + _mode + ".fileFilter")), RE.REG_ICASE); if (regexp.isMatch(low)) { setColorizing(_mode); modeSet = true; break; } } catch (REException ree) { } } if (!modeSet) setColorizing("plain"); document.addUndoableEditListener(this); document.addDocumentListener(this); parent.fireJextEvent(this, JextEvent.FILE_OPENED); } catch(BadLocationException bl) { bl.printStackTrace(); } catch(FileNotFoundException fnf) { String[] args = { path }; Utilities.showError(Jext.getProperty("textarea.file.notfound", args)); } catch(IOException io) { Utilities.showError(io.toString()); } finally { endOperation(); } } /** * Set the new flag and resets the default line end separator. */ public void setNewFlag(boolean newFlag) { newf = newFlag; //TODO: check if this is good. resetLineTerm(); lineTermSelector.setSelectedItem(getLineTermName()); } /** * Return true if current text is new, false otherwise. */ public boolean isNew() { return newf; } /** * Return true if area is empty, false otherwise. */ public boolean isEmpty() { if (getLength() == 0) return true; else return false; } /** * Return true if area content has changed, false otherwise. */ public boolean isDirty() { //this is to mark changed a file when //its line end has been changed. But it's probably a bug - if you clean() a TextArea //it can be still dirty. return dirty || isLineTermChanged(); } /** * Called when the content of the area has changed. */ private void setDirty() { dirty = true; } /** * Called after having saved or created a new document to ensure * the content isn't 'dirty'. */ public void clean() { dirty = false; } /** * Discard all edits contained in the UndoManager. * Update the corresponding menu items. */ public void discard() { undo.discardAllEdits(); } /** * Set the anchor postion. */ public void setAnchor() { try { anchor = document.createPosition(getCaretPosition()); } catch (BadLocationException ble) { } } /** * Go to anchor position */ public void gotoAnchor() { if (anchor == null) getToolkit().beep(); else setCaretPosition(anchor.getOffset()); } public int getAnchorOffset() { if (anchor == null) return -1; else return anchor.getOffset(); } /** * Used by Jext to update its menu items. */ public UndoManager getUndo() { return undo; } /** * Used for ReplaceAll. * This merges all text changes made between the beginCompoundEdit() * and the endCompoundEdit() calls into only one undo event. */ public void beginCompoundEdit() { beginCompoundEdit(true); } public void beginCompoundEdit(boolean cursorHandle) { if (compoundEdit == null && !protectedCompoundEdit) { endCurrentEdit(); compoundEdit = new CompoundEdit(); if (cursorHandle) waitingCursor(true); } } /** * A protected compound edit is a compound edit which cannot be ended by * a normal call to endCompoundEdit(). */ public void beginProtectedCompoundEdit() { if (!protectedCompoundEdit) { beginCompoundEdit(true); protectedCompoundEdit = true; } } /** * See beginCompoundEdit(). */ public void endCompoundEdit() { endCompoundEdit(true); } public void endCompoundEdit(boolean cursorHandle) { if (compoundEdit != null && !protectedCompoundEdit) { compoundEdit.end(); if (compoundEdit.canUndo()) undo.addEdit(compoundEdit); compoundEdit = null; if (cursorHandle) waitingCursor(false); } } /** * This terminates a protected compound edit. */ public void endProtectedCompoundEdit() { if (protectedCompoundEdit) { protectedCompoundEdit = false; endCompoundEdit(true); } } /** * Return the lentgh of the text in the area. */ public int getLength() { return document.getLength(); } /** * When an undoable event is fired, we add it to the undo/redo list. */ public void undoableEditHappened(UndoableEditEvent e) { if (!getOperation()) { if (compoundEdit == null) { currentEdit.addEdit(e.getEdit()); //undo.addEdit(e.getEdit()); } else compoundEdit.addEdit(e.getEdit()); } } public void endCurrentEdit() { if (currentEdit.isSignificant()) { currentEdit.end(); if (currentEdit.canUndo()) undo.addEdit(currentEdit); currentEdit = new CompoundEdit(); } } public void setUndoing(boolean action) { undoing = action; } /** * When a modification is made in the text, we turn * the 'to_be_saved' flag to true. */ public void changedUpdate(DocumentEvent e) { if (!getOperation()) { boolean savedDirty = isDirty(); setDirty(); if (!savedDirty) parent.setChanged(this); //it needs that the area is "dirty", so we have to call setDirty() before //isDirty can be true if the line end is changed or if dirty is true; } //setCaretPosition(e.getOffset() + e.getLength()); parent.fireJextEvent(this, JextEvent.CHANGED_UPDATE); } /** * When a modification is made in the text, we turn * the 'to_be_saved' flag to true. */ public void insertUpdate(DocumentEvent e) { if (!getOperation()) { boolean savedDirty = isDirty(); setDirty(); if (!savedDirty) parent.setChanged(this); //it needs that the area is "dirty", so we have to call setDirty() before //isDirty can be true if the line end is changed or if dirty is true; } if (undoing) { if (e.getLength() == 1) setCaretPosition(e.getOffset() + 1); else setCaretPosition(e.getOffset()); } parent.fireJextEvent(this, JextEvent.INSERT_UPDATE); } /** * When a modification is made in the text, we turn * the 'to_be_saved' flag to true. */ public void removeUpdate(DocumentEvent e) { parent.updateStatus(this); if (!getOperation()) { boolean savedDirty = isDirty(); setDirty(); if (!savedDirty) parent.setChanged(this); //it needs that the area is "dirty", so we have to call setDirty() before //isDirty can be true if the line end is changed or if dirty is true; } if (undoing) setCaretPosition(e.getOffset()); parent.fireJextEvent(this, JextEvent.REMOVE_UPDATE); } /** * Return a String representation of this object. */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append("JextTextArea: "); buf.append("[filename: " + getCurrentFile() + ";"); buf.append(" filesize: " + getLength() + "] -"); buf.append(" [is dirty: " + isDirty() + ";"); buf.append(" is new: " + isNew() + ";"); if (anchor != null) buf.append(" anchor: " + anchor.getOffset() + "] -"); else buf.append(" anchor: not defined] -"); buf.append(" [font-name: " + getFontName() + ";"); buf.append(" font-style: " + getFontStyle() + ";"); buf.append(" font-size: " + getFontSize() + "] -"); buf.append(" [syntax mode: " + mode + "]"); return buf.toString(); } ////////////////////////////////////////////////////////////////////////////////////////////// // INTERNAL CLASSES ////////////////////////////////////////////////////////////////////////////////////////////// class FocusHandler extends FocusAdapter { public void focusGained(FocusEvent evt) { if (!parent.getBatchMode()) { SwingUtilities.invokeLater(new Runnable() { public void run() { checkLastModificationTime(); } }); } } } class CaretHandler implements CaretListener { public void caretUpdate(CaretEvent evt) { parent.updateStatus(JextTextArea.this); } } class JextTextAreaPopupMenu extends Thread { private JextTextArea area; JextTextAreaPopupMenu(JextTextArea area) { super("---Thread:JextTextArea Popup---"); this.area = area; start(); } public void run() { popupMenu = XPopupReader.read(Jext.class.getResourceAsStream("jext.textarea.popup.xml"), "jext.textarea.popup.xml"); if (Jext.getFlatMenus()) popupMenu.setBorder(javax.swing.border.LineBorder.createBlackLineBorder()); area.setRightClickPopup(popupMenu); } } }// End of JextTextArea.java
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -