001: /*
002: * EditBus.java - The EditBus
003: * :tabSize=8:indentSize=8:noTabs=false:
004: * :folding=explicit:collapseFolds=1:
005: *
006: * Copyright (C) 1999 Slava Pestov
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public License
010: * as published by the Free Software Foundation; either version 2
011: * of the License, or any later version.
012: *
013: * This program is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with this program; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
021: */
022:
023: package org.gjt.sp.jedit;
024:
025: import java.util.*;
026: import org.gjt.sp.util.Log;
027:
028: /**
029: * jEdit's global event notification mechanism.<p>
030: *
031: * Plugins register with the EditBus to receive messages reflecting
032: * changes in the application's state, including changes in buffers,
033: * views and edit panes, changes in the set of properties maintained
034: * by the application, and the closing of the application.<p>
035: *
036: * The EditBus maintains a list of objects that have requested to receive
037: * messages. When a message is sent using this class, all registered
038: * components receive it in turn. Classes for objects that subscribe to
039: * the EditBus must implement the {@link EBComponent} interface, which
040: * defines the single method {@link EBComponent#handleMessage(EBMessage)}.<p>
041: *
042: * A plugin core class that extends the
043: * {@link EBPlugin} abstract class (and whose name ends with
044: * <code>Plugin</code> for identification purposes) will automatically be
045: * added to the EditBus during jEdit's startup routine. Any other
046: * class - for example, a dockable window that needs to receive
047: * notification of buffer changes - must perform its own registration by calling
048: * {@link #addToBus(EBComponent)} during its initialization.
049: * A convenient place to register in a class derived from <code>JComponent</code>
050: * would be in an implementation of the <code>JComponent</code> method
051: * <code>addNotify()</code>.<p>
052: *
053: * Message types sent by jEdit can be found in the
054: * {@link org.gjt.sp.jedit.msg} package.<p>
055: *
056: * Plugins can also send their own messages - any object can send a message to
057: * the EditBus by calling the static method {@link #send(EBMessage)}.
058: * Most plugins, however, only concern themselves with receiving, not
059: * sending, messages.
060: *
061: * @see org.gjt.sp.jedit.EBComponent
062: * @see org.gjt.sp.jedit.EBMessage
063: *
064: * @author Slava Pestov
065: * @author John Gellene (API documentation)
066: * @version $Id: EditBus.java 4669 2003-05-01 02:21:27Z spestov $
067: *
068: * @since jEdit 2.2pre6
069: */
070: public class EditBus {
071: //{{{ addToBus() method
072: /**
073: * Adds a component to the bus. It will receive all messages sent
074: * on the bus.
075: *
076: * @param comp The component to add
077: */
078: public static void addToBus(EBComponent comp) {
079: synchronized (components) {
080: components.add(comp);
081: copyComponents = null;
082: }
083: } //}}}
084:
085: //{{{ removeFromBus() method
086: /**
087: * Removes a component from the bus.
088: * @param comp The component to remove
089: */
090: public static void removeFromBus(EBComponent comp) {
091: synchronized (components) {
092: components.remove(comp);
093: copyComponents = null;
094: }
095: } //}}}
096:
097: //{{{ getComponents() method
098: /**
099: * Returns an array of all components connected to the bus.
100: */
101: public static EBComponent[] getComponents() {
102: synchronized (components) {
103: if (copyComponents == null) {
104: copyComponents = (EBComponent[]) components
105: .toArray(new EBComponent[components.size()]);
106: }
107: return copyComponents;
108: }
109: } //}}}
110:
111: //{{{ send() method
112: /**
113: * Sends a message to all components on the bus in turn.
114: * @param message The message
115: */
116: public static void send(EBMessage message) {
117: Log.log(Log.DEBUG, EditBus.class, message.toString());
118:
119: // To avoid any problems if components are added or removed
120: // while the message is being sent
121: EBComponent[] comps = getComponents();
122:
123: for (int i = 0; i < comps.length; i++) {
124: try {
125: EBComponent comp = comps[i];
126: if (Debug.EB_TIMER) {
127: long start = System.currentTimeMillis();
128: comp.handleMessage(message);
129: long time = (System.currentTimeMillis() - start);
130: if (time != 0) {
131: Log.log(Log.DEBUG, EditBus.class, comp + ": "
132: + time + " ms");
133: }
134: } else
135: comps[i].handleMessage(message);
136: } catch (Throwable t) {
137: Log.log(Log.ERROR, EditBus.class, "Exception"
138: + " while sending message on EditBus:");
139: Log.log(Log.ERROR, EditBus.class, t);
140: }
141: }
142: } //}}}
143:
144: //{{{ Private members
145: private static ArrayList components = new ArrayList();
146: private static EBComponent[] copyComponents;
147:
148: // can't create new instances
149: private EditBus() {
150: }
151: //}}}
152: }
|