⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractmainview.java~1~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~1~
📖 第 1 页 / 共 5 页
字号:
/*
 * 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.
			checkForModification = true;

		} // End of else if (actionCommand.equals("FileModified. ")).

	}


/*****************************************************************************/ 


	/**
	 * Adds a current text area listener.
	 *
	 * @param l The listener to add.
	 * @see #removeCurrentTextAreaListener
	 */
	public void addCurrentTextAreaListener(CurrentTextAreaListener l) {
		listenerList.add(CurrentTextAreaListener.class, l);
	}


/*****************************************************************************/ 


	/**
	 * Adds a document visually to this panel.
	 *
	 * @param title The name of the document to display.
	 * @param component The component to add (usually an RTextScrollPane).
	 * @param fileFullPath The full path to the file being displayed by the
	 *                     component.
	 */
	public abstract void addDocument(String title, Component component,
								String fileFullPath);


/*****************************************************************************/ 


	/**
	 * Adds an empty text file to this tabbed pane.  This method is
	 * synchronized so it doesn't interfere with the thread checking for files
	 * being modified outside of the editor.
	 *
	 * @param fileNameAndPath The full path and name of the file to add.
	 */
	private void addNewEmptyTextFile(String fileNameAndPath) {
		addNewEmptyTextFile(fileNameAndPath,
						RTextFileChooser.getDefaultEncoding());
	}


/*****************************************************************************/ 


	/**
	 * Adds an empty text file to this tabbed pane.  This method is

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -