📄 abstractmainview.java~2~
字号:
/*
* 03/19/2004
*
* AbstractMainView.java - Abstract class representing a collection of
* RTextEditorPanes. This class contains all logic that would be common to
* different implementations (i.e., everything except the view parts).
* Copyright (C) 2004 Robert Futrell
* email@address.com
* www.website.com
*
* This file is a part of RText.
*
* RText is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* RText is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.fife.rtext;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.imageio.ImageIO;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.EventListenerList;
import javax.swing.text.Caret;
import org.fife.io.UnicodeReader;
import org.fife.io.UnicodeWriter;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxHighlightingColorScheme;
import org.fife.ui.rtextarea.ConfigurableCaret;
import org.fife.ui.rtextarea.IconGroup;
import org.fife.ui.rtextarea.Macro;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextAreaEditorKit;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.fife.ui.rtextfilechooser.RTextFileChooser;
import org.fife.ui.search.*; // All search stuff.
/**
* Abstract class representing a collection of RTextEditorPanes. This class
* contains all logic that would be common to different implementations (i.e.,
* everything except the "view" parts).<p>
*
* An implementation of this class must fire a property change event of type
* <code>CURRENT_DOCUMENT_PROPERTY</code> whenever the currently-active
* document changes so that other pieces of RText can function properly.<p>
*
* RText plugins may wish to register to be
* <code>CurrentTextAreaListener</code>s if they want to be notified whenever
* a property of the currently-active text area (or the text area itself)
* changes.
*
* @author Robert Futrell
* @version 0.5
*/
public abstract class AbstractMainView
extends JPanel
implements PropertyChangeListener, ActionListener,
FindInFilesListener {
public static final int DOCUMENT_SELECT_TOP = JTabbedPane.TOP;
public static final int DOCUMENT_SELECT_LEFT = JTabbedPane.LEFT;
public static final int DOCUMENT_SELECT_BOTTOM = JTabbedPane.BOTTOM;
public static final int DOCUMENT_SELECT_RIGHT = JTabbedPane.RIGHT;
// Actions owned by the main view.
public static final int FIND_ACTION = 0;
public static final int FIND_NEXT_ACTION = 1;
public static final int REPLACE_ACTION = 2;
public static final int REPLACE_NEXT_ACTION = 3;
public static final int REPLACE_ALL_ACTION = 4;
public static final int FIND_IN_FILES_ACTION = 5;
public static final int PRINT_ACTION = 6;
public static final int PRINT_PREVIEW_ACTION = 7;
public static final int CLOSE_ACTION = 8;
public static final int CLOSE_ALL_ACTION = 9;
public static final int GOTO_ACTION = 10;
public static final int NUM_ACTIONS = 11;
public static final String CURRENT_DOCUMENT_PROPERTY =
"AbstractMainView.currentDocument";
public static final String FRACTIONAL_METRICS_PROPERTY =
"AbstractMainView.fractionalMetrics";
public static final String MARK_ALL_COLOR_PROPERTY =
"AbstractMainView.markAllColor";
public static final String NEW_FILE_ADDED_PROPERTY =
"AbstractMainView.newTextFileAdded";
public static final String OLD_FILE_ADDED_PROPERTY =
"AbstractMainView.oldTextFileAdded";
public static final String ROUNDED_SELECTION_PROPERTY =
"AbstractMainView.roundedSelection";
public static final String SMOOTH_TEXT_PROPERTY =
"AbstractMainView.smoothText";
public RTextEditorPane currentTextArea; // Pointer to currently active text area.
private Action[] actions;
public FindDialog findDialog; // The dialog that lets you search for text.
public ReplaceDialog replaceDialog; // The dialog that lets you replace text.
public Vector searchStrings; // The strings to go in the "Find What" combo boxes.
public boolean searchingForward; // If true, searching forward, false, searching backward.
public boolean searchMatchCase; // If true, match case while searching.
public boolean searchWholeWord; // If true, match searchString as not a substring of alphanumeric characters.
public boolean searchRegExpression; // If true, searchString is a Java regular expression.
public boolean searchMarkAll; // If true, all search results will be marked.
private boolean lineNumbersEnabled; // If true, line numbers are visible on the documents.
private boolean lineWrapEnabled; // If true, word wrap is enabled for all open documents.
public FindInFilesDialog findInFilesDialog; // Dialog for searching for text in files.
public GoToDialog goToDialog; // Dialog that lets you go to a certain line number.
private int textMode; // Either RTextEditorPane.INSERT_MODE or OVERWRITE_MODE.
private int tabSize; // The size (in spaces) tabs are.
private boolean emulateTabsWithWhitespace; // If true, tabs are emulated with spaces.
private Font printFont; // The font to use when printing a document.
private Color caretColor; // The color used for carets.
private Color selectionColor; // The color used for selections.
private Object backgroundObject; // The object to be used to draw text areas' backgrounds.
private float imageAlpha; // The alpha value to use for making the background image "translucent."
private String backgroundImageFileName; // Full path to the background image, or null if background is a color.
protected RText owner; // The owner of this tabbed panel.
private SyntaxFilters syntaxFilters; // The filters used to decide how to syntax highlight a file.
private boolean highlightCurrentLine; // Whether or not the current line is highlighted.
private Color currentLineColor; // The color with which to highlight the current line.
private boolean highlightModifiedDocumentDisplayNames; // If true, color display names of modified documents differently.
private Color modifiedDocumentDisplayNameColor; // Color to color display names of modified documents.
private boolean checkForModification = true; // Whether or not to check for files being modified outside of the docment.
private long modificationCheckDelay = 10000; // Delay in milliseconds.
private boolean bracketMatchingEnabled;
private Color matchedBracketBGColor;
private Color matchedBracketBorderColor;
private boolean marginLineEnabled;
private int marginLinePosition;
private Color marginLineColor;
private boolean whitespaceVisible; // Whether whitespace is visible in the text areas.
private boolean smoothTextEnabled; // Whether text is antialiased.
private boolean fractionalMetricsEnabled; // Whether fractional fontmetrics are used.
private Color markAllHighlightColor;
private boolean roundedSelectionEdges;
private int caretBlinkRate;
private int[] carets; // index 0=>insert, 1=>overwrite.
private EventListenerList listenerList;
/**
* The cursor used when recording a macro.
*/
private static Cursor macroCursor;
/*****************************************************************************/
/**
* Constructor.<p>
* You should call {@link #initialize} right after this.
*/
public AbstractMainView() {
super();
listenerList = new EventListenerList();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
checkFilesForOutsideModification();
}
}
,
modificationCheckDelay, // Initial delay.
modificationCheckDelay); // Check for files modified outside
// of the editor every 30 seconds.
}
/*****************************************************************************/
// Callback for various actions.
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
// If they click the "Find" button on the Find/Replace dialog...
if (actionCommand.equals("FindNext")) {
getAction(FIND_NEXT_ACTION).actionPerformed(null);
}
// If they click on the "Replace" button on the Replace dialog...
else if (actionCommand.equals("Replace")) {
getAction(REPLACE_NEXT_ACTION).actionPerformed(null);
}
// If they clicked on the "Replace All" button on the Replace dialog...
else if (actionCommand.equals("ReplaceAll")) {
getAction(REPLACE_ALL_ACTION).actionPerformed(null);
}
// If a file was found to be modified outside of the editor...
else if (actionCommand.startsWith("FileModified. ")) {
StringTokenizer tokenizer = new StringTokenizer(
actionCommand.substring(actionCommand.indexOf(' ')));
// Loop while there are still documents to prompt for.
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken(); // Should be the number of the next modified document.
try {
ResourceBundle msg = owner.getResourceBundle();
int docNumber = Integer.parseInt(token);
setSelectedIndex(docNumber);
// We must get it as a regular expression because replaceFirst
// expects one.
int rc = JOptionPane.NO_OPTION;
String temp = RTextUtilities.getRegularExpressionForLine(
currentTextArea.getFileName(), true);
if (temp != null) {
temp = msg.getString("DocModifiedMessage").replaceFirst(
"%documentName%", temp);
}
else {
temp = msg.getString("DocModifiedMessage"); // Just leave the %documentName$ in there.
}
rc = JOptionPane.showConfirmDialog(owner, temp,
msg.getString("ConfDialogTitle"),
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
// If they want to, reload the file.
if (rc == JOptionPane.YES_OPTION) {
try {
File f = new File(currentTextArea.getFileFullPath());
if (f.isFile()) { // Should always be true.
String oldEncoding = currentTextArea.getEncoding();
UnicodeReader uReader = new UnicodeReader(f, oldEncoding);
String encoding = uReader.getEncoding();
BufferedReader in = new BufferedReader(uReader);
currentTextArea.read(in, null); // Should dump old contents too.
uReader.close();
in.close();
currentTextArea.setEncoding(encoding);
currentTextArea.setModified(false);
moveToTopOfCurrentDocument();
}
else {
JOptionPane.showMessageDialog(owner,
msg.getString("ErrorReloadFNF"),
msg.getString("ErrorDialogTitle"),
JOptionPane.ERROR_MESSAGE);
}
}
catch (Exception ioe) {
JOptionPane.showMessageDialog(owner,
msg.getString("ErrorReadingFile") +
ioe,
msg.getString("ErrorDialogTitle"),
JOptionPane.ERROR_MESSAGE);
}
// This is needed because the text area's
// undoManager picked up the read() call above
// and added it as an insertion edit. We don't
// want the user to be able to undo this, however.
currentTextArea.discardAllEdits();
} // End of if (rc==JOptionPane.YES_OPTION)
}
catch (NumberFormatException nfe) {
owner.displayException(nfe);
}
// Whether or not we reload, we need to update the "last
// modified" time for this document, so we don't keep
// bugging them about the same outside modification.
currentTextArea.setLastModified(System.currentTimeMillis());
} // End of while (token != null).
// It's okay to start checking for modifications again.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -