Source code: javatools/swing/VariablePaneDispatcher.java
1 /*
2 * VariablePaneDispatcher.java
3 *
4 * Created on 17 ottobre 2002, 19.05
5 Javatools (modified version) - Some useful general classes.
6 Copyright (C) 2002-2003 Chris Bitmead (original) Antonio Petrelli (modified)
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) 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 Contact me at: brenmcguire@users.sourceforge.net
23 */
24
25 package javatools.swing;
26
27 import java.util.*;
28 import java.text.MessageFormat;
29 import javatools.util.*;
30 import javatools.db.*;
31 import javatools.swing.internal.*;
32
33 /** It represents an "event dispatcher" to be used to manage a "variable pane" i.e.
34 * a pane that changes depending on a particular selection in another place of
35 * the application.
36 * You have to inherit only this method:
37 * <CODE>initialize</CODE>: to init the panels, if you need it.
38 * Set the <CODE>panelName</CODE> to your own name, to differentiate between
39 * different <CODE>VariablePaneDispatcher</CODE>'s.
40 * Create your panels, put them in <CODE>type2panel</CODE> HashMap, depending on
41 * the type of the (<CODE>Clippable</CODE>) object to be displayed.
42 * Put your messages in <CODE>type2message</CODE> HashMap (depending on ther type)
43 * and make all you need for your panels.
44 * The panels must be of the type <CODE>IndexablePanel</CODE>. All the dispatching
45 * is internal.
46 * Use this sequence of commands:
47 * <CODE>VariablePaneDispatcher disp = new VariablePaneDispatcher();
48 * disp.setContainer(theContainerToContainThePanels);
49 * disp.setStatusLabelSync(myStatusLabelSync);
50 * disp.start();
51 * -- repeat
52 * disp.setObject(myOwnClippableObject);
53 * -- until you need it.
54 * disp.stopAll();
55 * </CODE>
56 * @author Antonio Petrelli
57 */
58 public abstract class VariablePaneDispatcher extends java.lang.Thread {
59
60 /** Creates a new instance of VariablePaneDispatcher */
61 public VariablePaneDispatcher() {
62 initialized = false;
63 obj = null;
64 previousObj = null;
65 panelHider = null;
66 type2panel = new HashMap();
67 type2message = new HashMap();
68 formatter = new MessageFormat("");
69 processing = true;
70 }
71
72 /** Ovverrides thread's <CODE>start</CODE> method.
73 */
74 public void start() {
75 doInitialize();
76 super.start();
77 }
78
79 /** Thread's run method.
80 */
81 public void run() {
82 stoppedExternally = false;
83 doDispatch();
84 }
85
86 /** Stops the thread.
87 */
88 public synchronized void stopAll() {
89 stoppedExternally = true;
90 notifyAll();
91 }
92
93 /** Sets the object that you want its details to be displayed.
94 * @param pObj The object to use.
95 */
96 public void setObject(Clippable pObj) {
97 obj = pObj;
98 if (!processing)
99 restartDispatch();
100 }
101
102 /** Sets the container that will contain the panels.
103 * @param cont The container to use.
104 */
105 public synchronized void setContainer(java.awt.Container cont) {
106 refContainer = cont;
107 panelDisplayer = new VPDPanelDisplayer(refContainer);
108 }
109
110 /** Sets the status label sync to display status messages.
111 * @param sync The status label sync to use.
112 */
113 public void setStatusLabelSync(StatusLabelSync sync) {
114 statusSync = sync;
115 }
116
117 /** Dispatches the requests.
118 */
119 protected synchronized void doDispatch() {
120 if (obj != null)
121 doDispatchOne();
122 else
123 processing = false;
124
125 while (!stoppedExternally) {
126 try {
127 wait();
128 }
129 catch (InterruptedException e) {
130 System.out.println(e.getMessage());
131 }
132
133 if (stoppedExternally)
134 return;
135 if (previousObj == obj) {
136 processing = false;
137 }
138
139 if (processing)
140 doDispatchOne();
141 }
142 }
143
144 /** It will be called when the thread starts. Inherit it and put your initialization
145 * code.
146 */
147 protected abstract void initialize();
148
149 /** The container to be used.
150 */
151 protected java.awt.Container refContainer;
152
153 /** Maps types and panels
154 */
155 protected HashMap type2panel;
156
157 /** Maps types and message to be displayed into a status bar.
158 */
159 protected HashMap type2message;
160
161 /** The object you want to display its details.
162 */
163 protected Clippable obj;
164
165 /** The previous selected object. If you need it, use it...
166 */
167 protected Clippable previousObj;
168 /** Checks whether the thread has been stopped externally.
169 */
170 protected boolean stoppedExternally;
171 /** Checks whether the thread has been initialized.
172 */
173 protected boolean initialized;
174 /** Contains the panel name, to be used as a "thread name" for the status sync label.
175 */
176 protected String panelName;
177
178 private boolean processing;
179 private StatusLabelSync statusSync;
180 private Collection paneCollection;
181 private VPDPanelHider panelHider;
182 private VPDPanelDisplayer panelDisplayer;
183
184 private static MessageFormat formatter;
185
186 private synchronized void doInitialize() {
187 Object[] tempArray;
188 String output, pattern;
189
190 pattern = java.util.ResourceBundle.getBundle("res/JavatoolsBundle").getString("Starting_something");
191 formatter.applyPattern(pattern);
192 tempArray = new Object[1];
193 tempArray[0] = panelName;
194 output = formatter.format(tempArray);
195 statusSync.setMessage(panelName, output);
196 initialize();
197 paneCollection = type2panel.values();
198 panelHider = new VPDPanelHider(paneCollection);
199 refContainer.removeAll();
200 initialized = true;
201 statusSync.removeMessage(panelName);
202 }
203
204 private synchronized void restartDispatch() {
205 processing = true;
206 notifyAll();
207 }
208
209 private synchronized void doDispatchOne() {
210 Clippable tempObj;
211 javatools.swing.IndexablePanel tempPanel;
212 String type, tempMessage;
213
214 do {
215 tempObj = obj;
216 type = tempObj.getType();
217 tempMessage = (String) type2message.get(type);
218 if (tempMessage != null)
219 statusSync.setMessage(panelName, tempMessage);
220 MoreSwingUtilities.invokeWakingUp(panelHider);
221 previousObj = obj;
222 tempPanel = (javatools.swing.IndexablePanel)
223 type2panel.get(type);
224 if (tempPanel != null) {
225 panelDisplayer.showPanel(tempPanel);
226 tempPanel.setID(tempObj.getValue());
227 }
228 statusSync.removeMessage(panelName);
229 } while (tempObj != obj && !stoppedExternally);
230 processing = false;
231 }
232 }