Source code: org/gjt/sp/jedit/EditBus.java
1 /*
2 * EditBus.java - The EditBus
3 * :tabSize=8:indentSize=8:noTabs=false:
4 * :folding=explicit:collapseFolds=1:
5 *
6 * Copyright (C) 1999 Slava Pestov
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 package org.gjt.sp.jedit;
24
25 import java.util.*;
26 import org.gjt.sp.util.Log;
27
28 /**
29 * jEdit's global event notification mechanism.<p>
30 *
31 * Plugins register with the EditBus to receive messages reflecting
32 * changes in the application's state, including changes in buffers,
33 * views and edit panes, changes in the set of properties maintained
34 * by the application, and the closing of the application.<p>
35 *
36 * The EditBus maintains a list of objects that have requested to receive
37 * messages. When a message is sent using this class, all registered
38 * components receive it in turn. Classes for objects that subscribe to
39 * the EditBus must implement the {@link EBComponent} interface, which
40 * defines the single method {@link EBComponent#handleMessage(EBMessage)}.<p>
41 *
42 * A plugin core class that extends the
43 * {@link EBPlugin} abstract class (and whose name ends with
44 * <code>Plugin</code> for identification purposes) will automatically be
45 * added to the EditBus during jEdit's startup routine. Any other
46 * class - for example, a dockable window that needs to receive
47 * notification of buffer changes - must perform its own registration by calling
48 * {@link #addToBus(EBComponent)} during its initialization.
49 * A convenient place to register in a class derived from <code>JComponent</code>
50 * would be in an implementation of the <code>JComponent</code> method
51 * <code>addNotify()</code>.<p>
52 *
53 * Message types sent by jEdit can be found in the
54 * {@link org.gjt.sp.jedit.msg} package.<p>
55 *
56 * Plugins can also send their own messages - any object can send a message to
57 * the EditBus by calling the static method {@link #send(EBMessage)}.
58 * Most plugins, however, only concern themselves with receiving, not
59 * sending, messages.
60 *
61 * @see org.gjt.sp.jedit.EBComponent
62 * @see org.gjt.sp.jedit.EBMessage
63 *
64 * @author Slava Pestov
65 * @author John Gellene (API documentation)
66 * @version $Id: EditBus.java,v 1.11 2003/05/01 02:21:26 spestov Exp $
67 *
68 * @since jEdit 2.2pre6
69 */
70 public class EditBus
71 {
72 //{{{ addToBus() method
73 /**
74 * Adds a component to the bus. It will receive all messages sent
75 * on the bus.
76 *
77 * @param comp The component to add
78 */
79 public static void addToBus(EBComponent comp)
80 {
81 synchronized(components)
82 {
83 components.add(comp);
84 copyComponents = null;
85 }
86 } //}}}
87
88 //{{{ removeFromBus() method
89 /**
90 * Removes a component from the bus.
91 * @param comp The component to remove
92 */
93 public static void removeFromBus(EBComponent comp)
94 {
95 synchronized(components)
96 {
97 components.remove(comp);
98 copyComponents = null;
99 }
100 } //}}}
101
102 //{{{ getComponents() method
103 /**
104 * Returns an array of all components connected to the bus.
105 */
106 public static EBComponent[] getComponents()
107 {
108 synchronized(components)
109 {
110 if (copyComponents == null)
111 {
112 copyComponents = (EBComponent[])components.toArray(
113 new EBComponent[components.size()]);
114 }
115 return copyComponents;
116 }
117 } //}}}
118
119 //{{{ send() method
120 /**
121 * Sends a message to all components on the bus in turn.
122 * @param message The message
123 */
124 public static void send(EBMessage message)
125 {
126 Log.log(Log.DEBUG,EditBus.class,message.toString());
127
128 // To avoid any problems if components are added or removed
129 // while the message is being sent
130 EBComponent[] comps = getComponents();
131
132 for(int i = 0; i < comps.length; i++)
133 {
134 try
135 {
136 EBComponent comp = comps[i];
137 if(Debug.EB_TIMER)
138 {
139 long start = System.currentTimeMillis();
140 comp.handleMessage(message);
141 long time = (System.currentTimeMillis() - start);
142 if(time != 0)
143 {
144 Log.log(Log.DEBUG,EditBus.class,comp + ": " + time + " ms");
145 }
146 }
147 else
148 comps[i].handleMessage(message);
149 }
150 catch(Throwable t)
151 {
152 Log.log(Log.ERROR,EditBus.class,"Exception"
153 + " while sending message on EditBus:");
154 Log.log(Log.ERROR,EditBus.class,t);
155 }
156 }
157 } //}}}
158
159 //{{{ Private members
160 private static ArrayList components = new ArrayList();
161 private static EBComponent[] copyComponents;
162
163 // can't create new instances
164 private EditBus() {}
165 //}}}
166 }