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

📄 rtaupdatehandler.java~1~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~1~
字号:
/*
 * 07/29/2004
 *
 * RTAUpdateHandler.java - Layout manager for the text area, and also forwards
 *                         document changes to the view.
 * Copyright (C) 2004 Robert Futrell
 * email@address.com
 * www.website.com
 *
 * This program 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.
 *
 * This program 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.ui.rtextarea;

import java.awt.*;
import java.awt.dnd.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.TooManyListenersException;
import javax.swing.event.*;
import javax.swing.plaf.UIResource;
import javax.swing.text.*;


/**
 * Gets attached to the model (document) in an <code>RTextArea</code> and
 * listens for document events.  Forwards any document events to the root view
 * so it can update accordingly.  Also lays out the text area and handles focus
 * accelerator changes.<p>This class is pretty much ripped off from a subclass
 * in <code>BasicTextUI</code>.
 *
 * @author Robert Futrell
 * @version 0.1
 */
class RTAUpdateHandler implements PropertyChangeListener, DocumentListener,
								LayoutManager2 {

	/**
	 * The "layout constraints" for the LayoutManager2 implementation.
	 * These are View objects for those components that are represented
	 * by a View in the View tree.
	 */
	private Hashtable constraints;

	private RTextAreaUI ui;


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


	/**
	 * Constructor.
	 */
	RTAUpdateHandler(RTextAreaUI ui) {
		this.ui = ui;
	}


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


	/**
	 * This method gets called when a bound property is changed.
	 * We are looking for document changes on the editor.
	 */
	public final void propertyChange(PropertyChangeEvent evt) {

		Object oldValue = evt.getOldValue();
		Object newValue = evt.getNewValue();
		String propertyName = evt.getPropertyName();

		// Both are documents, but either could be null.
		if ((oldValue instanceof Document) || (newValue instanceof Document)) {

			if (oldValue != null)
				((Document)oldValue).removeDocumentListener(this);

			if (newValue != null) {
				((Document)newValue).addDocumentListener(this);
				if ("document" == propertyName) {
					ui.setView(null);
					ui.propertyChange(evt);
					ui.modelChanged();
					return;
				}
			}

			ui.modelChanged();

		}

		if ("focusAccelerator" == propertyName) {
			ui.updateFocusAcceleratorBinding(true);
		}

		else if ("componentOrientation" == propertyName) {
			// Changes in ComponentOrientation require the views to be
			// rebuilt.
			ui.modelChanged();
		}

		else if ("font" == propertyName) {
			ui.modelChanged();
		}

		else if ("transferHandler" == propertyName) {
			DropTarget dropTarget = ui.getRTextArea().getDropTarget();
			if (dropTarget instanceof UIResource) {
				if (RTextAreaUI.dropTargetListener == null)
                        RTextAreaUI.dropTargetListener = new RTADropTargetListener();
			}
			try {
				dropTarget.addDropTargetListener(RTextAreaUI.dropTargetListener);
			} catch (TooManyListenersException tmle) {
				// should not happen... swing drop target is multicast
			}
		}

		else if ("editable" == propertyName) {
			ui.modelChanged();
		}

		ui.propertyChange(evt);

	}


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


	/**
	 * The insert notification.  Gets sent to the root of the view structure
	 * that represents the portion of the model being represented by the
	 * editor.  The factory is added as an argument to the update so that
	 * the views can update themselves in a dynamic (not hardcoded) way.
	 *
	 * @param e  The change notification from the currently associated
	 *           document.
	 * @see DocumentListener#insertUpdate
	 */
	public final void insertUpdate(DocumentEvent e) {
		Rectangle alloc = (ui.painted) ? ui.getVisibleEditorRect() : null;
		ui.rootView.insertUpdate(e, alloc);
	}


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


	/**
	 * The remove notification.  Gets sent to the root of the view structure
	 * that represents the portion of the model being represented by the
	 * editor.  The factory is added as an argument to the update so that
	 * the views can update themselves in a dynamic (not hardcoded) way.
	 *
	 * @param e  The change notification from the currently associated
	 *  document.
	 * @see DocumentListener#removeUpdate
	 */
	public final void removeUpdate(DocumentEvent e) {
		Rectangle alloc = (ui.painted) ? ui.getVisibleEditorRect() : null;
		ui.rootView.removeUpdate(e, alloc);
	}


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


	/**
	 * The change notification.  Gets sent to the root of the view structure
	 * that represents the portion of the model being represented by the
	 * editor.  The factory is added as an argument to the update so that
	 * the views can update themselves in a dynamic (not hardcoded) way.
	 *
	 * @param e  The change notification from the currently associated
	 *  document.
	 * @see DocumentListener#changeUpdate
	 */
	public final void changedUpdate(DocumentEvent e) {
		Rectangle alloc = (ui.painted) ? ui.getVisibleEditorRect() : null;
		ui.rootView.changedUpdate(e, alloc);
	}


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


	/**
	 * Adds the specified component with the specified name to
	 * the layout.
	 * @param name the component name
	 * @param comp the component to be added
	 */
	public void addLayoutComponent(String name, Component comp) {
		// not supported
	}


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


	/**
	 * Removes the specified component from the layout.
	 * @param comp the component to be removed
	 */
	public void removeLayoutComponent(Component comp) {
		if (constraints != null) {
			// remove the constraint record
			constraints.remove(comp);
		}
	}


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


	/**
	 * Calculates the preferred size dimensions for the specified 
	 * panel given the components in the specified parent container.
	 * @param parent the component to be laid out
	 *  
	 * @see #minimumLayoutSize
	 */
	public Dimension preferredLayoutSize(Container parent) {
		// should not be called (JComponent uses UI instead)
		return null;
	}


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


	/** 
	 * Calculates the minimum size dimensions for the specified 
	 * panel given the components in the specified parent container.
	 * @param parent the component to be laid out
	 * @see #preferredLayoutSize
	 */
	public Dimension minimumLayoutSize(Container parent) {
		// should not be called (JComponent uses UI instead)
		return null;
	}


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


	/** 
	 * Lays out the container in the specified panel.  This is
	 * implemented to position all components that were added
	 * with a View object as a constraint.  The current allocation
	 * of the associated View is used as the location of the 
	 * component.
	 * <p>
	 * A read-lock is acquired on the document to prevent the
	 * view tree from being modified while the layout process
	 * is active.
	 *
	 * @param parent the component which needs to be laid out 
	 */
	public void layoutContainer(Container parent) {
		if ((constraints != null) && (! constraints.isEmpty())) {
			Rectangle alloc = ui.getVisibleEditorRect();
			if (alloc != null) {
				RTextAreaDocument doc = (RTextAreaDocument)ui.
										getRTextArea().getDocument();
				doc.readLock();
				try {
					ui.rootView.setSize(alloc.width, alloc.height);
					Enumeration components = constraints.keys();
					while (components.hasMoreElements()) {
						Component comp = (Component) components.nextElement();
						View v = (View) constraints.get(comp);
						Shape ca = calculateViewPosition(alloc, v);
						if (ca != null) {
							Rectangle compAlloc = (ca instanceof Rectangle) ? 
												(Rectangle) ca : ca.getBounds();
							comp.setBounds(compAlloc);
						}
					}
				} finally {
					doc.readUnlock();
				}			
			}
		}
	}


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


	/**
	 * Find the Shape representing the given view.
	 */
	Shape calculateViewPosition(Shape alloc, View v) {
		int pos = v.getStartOffset();
		View child = null;
		for (View parent=ui.rootView; (parent!=null) && (parent!=v); parent=child) {
			int index = parent.getViewIndex(pos, Position.Bias.Forward);
			alloc = parent.getChildAllocation(index, alloc);
			child = parent.getView(index);
		}
		return (child != null) ? alloc : null;
	}


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


	/**
	 * Adds the specified component to the layout, using the specified
	 * constraint object.  We only store those components that were added
	 * with a constraint that is of type View.
	 *
	 * @param comp the component to be added
	 * @param constraint  where/how the component is added to the layout.
	 */
	public void addLayoutComponent(Component comp, Object constraint) {
		if (constraint instanceof View) {
			if (constraints == null)
				constraints = new Hashtable(7);
			constraints.put(comp, constraint);
		}
	}


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


	/** 
	 * Returns the maximum size of this component.
	 * @see java.awt.Component#getMinimumSize()
	 * @see java.awt.Component#getPreferredSize()
	 * @see LayoutManager
	 */
	public Dimension maximumLayoutSize(Container target) {
		// should not be called (JComponent uses UI instead)
		return null;
	}


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


	/**
	 * Returns the alignment along the x axis.  This specifies how
	 * the component would like to be aligned relative to other 
	 * components.  The value should be a number between 0 and 1
	 * where 0 represents alignment along the origin, 1 is aligned
	 * the furthest away from the origin, 0.5 is centered, etc.
	 */
	public float getLayoutAlignmentX(Container target) {
		return 0.5f;
	}


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


	/**
	 * Returns the alignment along the y axis.  This specifies how
	 * the component would like to be aligned relative to other 
	 * components.  The value should be a number between 0 and 1
	 * where 0 represents alignment along the origin, 1 is aligned
	 * the furthest away from the origin, 0.5 is centered, etc.
	 */
	public float getLayoutAlignmentY(Container target) {
		return 0.5f;
	}


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


	/**
	 * Invalidates the layout, indicating that if the layout manager
	 * has cached information it should be discarded.
	 */
	public void invalidateLayout(Container target) {
	}


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

}

⌨️ 快捷键说明

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