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

📄 abstractmainview.java~2~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~2~
📖 第 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.

⌨️ 快捷键说明

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