📄 dockablewindowmanager.java
字号:
/* * DockableWindowManager.java - manages dockable windows * :tabSize=8:indentSize=8:noTabs=false: * :folding=explicit:collapseFolds=1: * * Copyright (C) 2000, 2001 Slava Pestov * * 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.gjt.sp.jedit.gui;//{{{ Importsimport bsh.EvalError;import bsh.NameSpace;import com.microstar.xml.*;import org.gjt.sp.jedit.*;import org.gjt.sp.util.Log;import javax.swing.*;import java.awt.*;import java.io.*;import java.util.*;//}}}/** * The <code>DockableWindowManager</code> keeps track of dockable windows. * Each {@link org.gjt.sp.jedit.View} has an instance of this class.<p> * * <b>dockables.xml:</b><p> * * Dockable window definitions are read from <code>dockables.xml</code> files * contained inside plugin JARs. A dockable definition file has the following * form: * * <pre><?xml version="1.0"?> *<!DOCTYPE DOCKABLES SYSTEM "dockables.dtd"> *<DOCKABLES> * <DOCKABLE NAME="name"> * // Code to create the dockable * </DOCKABLE> *</DOCKABLES></pre> * * More than one <code><DOCKABLE><code> tag may be present. The code that * creates the dockable can reference any BeanShell built-in variable * (see {@link org.gjt.sp.jedit.BeanShell}), along with a variable * <code>position</code> whose value is one of * {@link #FLOATING}, {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, * and {@link #RIGHT}.<p> * * The following properties must be defined for each dockable window: * * <ul> * <li><code><i>name</i>.title</code> - the string to show in the title bar * of the dockable.</li> * <li><code><i>name</i>.label</code> - the dockable's menu item label.</li> * </ul> * * A number of actions are automatically created for each dockable window: * * <ul> * <li><code><i>name</i></code> - opens the dockable window.</li> * <li><code><i>name</i>-toggle</code> - toggles the dockable window's visibility.</li> * <li><code><i>name</i>-float</code> - opens the dockable window in a new * floating window.</li> * </ul> * * Note that only the first action needs a <code>label</code> property, the * rest have automatically-generated labels. * * <b>Implementation details:</b><p> * * When an instance of this class is initialized by the {@link org.gjt.sp.jedit.View} * class, it * iterates through the list of registered dockable windows (from jEdit itself, * and any loaded plugins) and * examines options supplied by the user in the <b>Global * Options</b> dialog box. Any plugins designated for one of the * four docking positions are displayed.<p> * * To create an instance of a dockable window, the <code>DockableWindowManager</code> * finds and executes the BeanShell code extracted from the appropriate * <code>dockables.xml</code> file. This code will typically consist of a call * to the constructor of the dockable window component. The result of the * BeanShell expression, typically a newly constructed component, is placed * in a window managed by this class. * * @see org.gjt.sp.jedit.View#getDockableWindowManager() * * @author Slava Pestov * @author John Gellene (API documentation) * @version $Id: DockableWindowManager.java,v 1.49 2003/02/11 02:31:06 spestov Exp $ * @since jEdit 2.6pre3 */public class DockableWindowManager extends JPanel{ //{{{ Static part of class //{{{ Constants /** * Floating position. * @since jEdit 2.6pre3 */ public static final String FLOATING = "floating"; /** * Top position. * @since jEdit 2.6pre3 */ public static final String TOP = "top"; /** * Left position. * @since jEdit 2.6pre3 */ public static final String LEFT = "left"; /** * Bottom position. * @since jEdit 2.6pre3 */ public static final String BOTTOM = "bottom"; /** * Right position. * @since jEdit 2.6pre3 */ public static final String RIGHT = "right"; //}}} //{{{ loadDockableWindows() method /** * Plugins shouldn't need to call this method. * @since jEdit 4.0pre1 */ public static boolean loadDockableWindows(String path, Reader in, ActionSet actionSet) { try { //Log.log(Log.DEBUG,jEdit.class,"Loading dockables from " + path); DockableListHandler dh = new DockableListHandler(path,actionSet); XmlParser parser = new XmlParser(); parser.setHandler(dh); parser.parse(null, null, in); return true; } catch(XmlException xe) { int line = xe.getLine(); String message = xe.getMessage(); Log.log(Log.ERROR,jEdit.class,path + ":" + line + ": " + message); } catch(Exception e) { Log.log(Log.ERROR,jEdit.class,e); } return false; } //}}} //{{{ registerDockableWindow() method public static void registerDockableWindow(String name, String code, boolean actions, ActionSet actionSet) { dockableWindowFactories.addElement(new Factory(name,code, actions,actionSet)); } //}}} //{{{ getRegisteredDockableWindows() method public static String[] getRegisteredDockableWindows() { String[] retVal = new String[dockableWindowFactories.size()]; for(int i = 0; i < dockableWindowFactories.size(); i++) { retVal[i] = ((Factory)dockableWindowFactories.elementAt(i)).name; } return retVal; } //}}} //{{{ DockableListHandler class static class DockableListHandler extends HandlerBase { //{{{ DockableListHandler constructor DockableListHandler(String path, ActionSet actionSet) { this.path = path; this.actionSet = actionSet; stateStack = new Stack(); actions = true; } //}}} //{{{ resolveEntity() method public Object resolveEntity(String publicId, String systemId) { if("dockables.dtd".equals(systemId)) { // this will result in a slight speed up, since we // don't need to read the DTD anyway, as AElfred is // non-validating return new StringReader("<!-- -->"); /* try { return new BufferedReader(new InputStreamReader( getClass().getResourceAsStream ("/org/gjt/sp/jedit/dockables.dtd"))); } catch(Exception e) { Log.log(Log.ERROR,this,"Error while opening" + " dockables.dtd:"); Log.log(Log.ERROR,this,e); } */ } return null; } //}}} //{{{ attribute() method public void attribute(String aname, String value, boolean isSpecified) { aname = (aname == null) ? null : aname.intern(); value = (value == null) ? null : value.intern(); if(aname == "NAME") dockableName = value; else if(aname == "NO_ACTIONS") actions = (value == "FALSE"); } //}}} //{{{ doctypeDecl() method public void doctypeDecl(String name, String publicId, String systemId) throws Exception { if("DOCKABLES".equals(name)) return; Log.log(Log.ERROR,this,path + ": DOCTYPE must be DOCKABLES"); } //}}} //{{{ charData() method public void charData(char[] c, int off, int len) { String tag = peekElement(); String text = new String(c, off, len); if (tag == "DOCKABLE") { code = text; } } //}}} //{{{ startElement() method public void startElement(String tag) { tag = pushElement(tag); } //}}} //{{{ endElement() method public void endElement(String name) { if(name == null) return; String tag = peekElement(); if(name.equals(tag)) { if(tag == "DOCKABLE") { registerDockableWindow(dockableName, code,actions,actionSet); // make default be true for the next // action actions = true; } popElement(); } else { // can't happen throw new InternalError(); } } //}}} //{{{ startDocument() method public void startDocument() { try { pushElement(null); } catch (Exception e) { e.printStackTrace(); } } //}}} //{{{ Private members //{{{ Instance variables private String path; private ActionSet actionSet; private String dockableName; private String code; private boolean actions; private Stack stateStack; //}}} //{{{ pushElement() method private String pushElement(String name) { name = (name == null) ? null : name.intern(); stateStack.push(name); return name; } //}}} //{{{ peekElement() method private String peekElement() { return (String) stateStack.peek(); } //}}} //{{{ popElement() method private String popElement() { return (String) stateStack.pop(); } //}}} //}}} } //}}} //{{{ Factory class static class Factory { // we assume dockable window code is not called // recursively... private static NameSpace nameSpace = new NameSpace( BeanShell.getNameSpace(),"dockable window"); String name; String code; //{{{ Factory constructor Factory(String name, String code, boolean actions, ActionSet actionSet) { this.name = name; this.code = code; if(actions) { actionSet.addAction(new OpenAction()); actionSet.addAction(new ToggleAction()); actionSet.addAction(new FloatAction()); } } //}}} //{{{ createDockableWindow() method JComponent createDockableWindow(View view, String position) { try { BeanShell.getNameSpace().setVariable( "position",position); } catch(EvalError e) { Log.log(Log.ERROR,this,e); } JComponent win = (JComponent)BeanShell.eval(view, nameSpace,code); return win; } //}}} //{{{ OpenAction class class OpenAction extends EditAction { //{{{ OpenAction constructor OpenAction() { super(name); } //}}} //{{{ invoke() method public void invoke(View view) { view.getDockableWindowManager() .showDockableWindow(name); } //}}} //{{{ getCode() method public String getCode() { return "view.getDockableWindowManager()" + ".showDockableWindow(\"" + name + "\");"; } //}}} } //}}} //{{{ ToggleAction class class ToggleAction extends EditAction { //{{{ ToggleAction constructor ToggleAction() { super(name + "-toggle"); } //}}} //{{{ invoke() method public void invoke(View view) { view.getDockableWindowManager() .toggleDockableWindow(name); } //}}} //{{{ isToggle() method public boolean isToggle() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -