Source code: junk/JXDefaultWM.java
1 /*
2 * @(#)JXDefaultWM.java
3 * Copyright (C) 2001-2003 Tay Hock Keong <tay_ivan@hotmail.com>
4 * This file is part of JD4X.
5 * JD4X is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 * JD4X is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with JD4X; see the file COPYING. If not, write to the Free
15 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16 */
17
18 package junk;
19
20 import junk.gui.background.*;
21 import junk.util.*;
22 import junk.gui.*;
23 import junk.images.*;
24 import arch.message.error.*;
25 import arch.module.data.*;
26 import arch.module.icore.*;
27 import arch.module.minor.*;
28 import arch.message.request.*;
29 import arch.task.*;
30 import arch.task.supported.*;
31 import moth.*;
32 import java.awt.*;
33 import java.awt.event.*;
34 import javax.swing.*;
35 import javax.swing.border.*;
36 import java.util.*;
37
38 /**
39 * JXDefaultWM is the default Java window manager for the JD4X desktop. It has
40 * to be first registered with Moth before it can take effect. JUNK is responsible
41 * for selecting the desired window manager and registering it with Moth. Once the
42 * window manager has been determined, Moth will notify it whenever an event of
43 * interest occurs. The Java window manager is free to make any decisions regarding
44 * window behaviors. In this way the Java window manager controls the desktop
45 * without lossing too much performance. The degree of control that the Java
46 * window manager has, will depend on the specific platform implementation of
47 * the windowing module (in the default case, Moth). Although the default Java
48 * window manager implements a standard desktop user interface, Java developers
49 * are not restricted to them. With the standard JD4X window manager interface,
50 * Java developers are free to implement desktop pagers, user workspace and etc.
51 * <BR>Refer to the section on extending the JD4X desktop in the design and
52 * specification document (dns.sxw) for more details of how to develop your own
53 * Java window manager.
54 * @see arch.module.icore.JXWindowManager
55 * @see arch.module.minor.JXMinorModule
56 * @version 0.1, 27/06/2003
57 * @since JD4X 1.0
58 * @author Tay Hock Keong
59 */
60 public class JXDefaultWM extends JXMinorModule implements JXWindowManagerInterface{
61
62 /** Desktop background. */
63 private JXBackground pseudoRoot;
64
65 /** Desktop task bar. */
66 private JPanel taskBar;
67
68 /** Desktop menu. */
69 private JMenu dm;
70
71 /** Icon manager. */
72 private JPanel iconManager;
73
74 /** Applet manager. */
75 private JPanel appletManager;
76
77 /** General desired iconfy and deiconfy action. */
78 private IconAction ia;
79
80 /** Active window collection. */
81 private Hashtable winTable;
82
83 /** Window manager ID */
84 public static final int WM_ID=130;
85
86 /**
87 * Default constructor.
88 */
89 public JXDefaultWM(){
90 super();
91 setModuleID(WM_ID);
92 setVersion(0.1F);
93 }
94
95 /**
96 * Add a new desktop GUI component to the window manager task bar.
97 * The default JD4X window manager currently only supports:
98 * JMenu, JMenuItem, JButton, JPanel and JApplet.
99 * @param tb
100 * the new desktop component.
101 */
102 public void addDesktopGUI(JComponent c){
103 if(c != null){
104 if((c instanceof JMenu) || (c instanceof JMenuItem)){
105 dm.add(c);
106 }
107 else{
108 appletManager.add(c);
109 }
110 }
111 }
112
113 /**
114 * It allows the module developer to provide his/her information. The basic
115 * information should be short and should include the following format each
116 * on its own line:
117 * <BR>Module: Name, version
118 * <BR>Develop By: Name, <Email>. Name, <Email>. [...]
119 * @return
120 * the credit information that the developer desires to be displayed.
121 * <dt><b>Postcondition:</b><dd>
122 * The information to be displayed will be added to the global information
123 * panel. The display panel is implementation dependent.
124 */
125 public String getCredits(){
126 String m = toString();
127 m = m.replaceAll("<", "<");
128 m = m.replaceAll(">", ">");
129 StringBuffer temp = new StringBuffer("<BR>Module: ").append(m).
130 append("<BR>Develop By: Tay Hock Keong, <tay_ivan@hotmail.com>.");
131 return temp.toString();
132 }
133
134 /**
135 * Initialize all GUI components for client interaction.
136 * @return
137 * the desktop menu for the controller.
138 */
139 public JComponent getDesktopGUI(){
140 JXConfigMenusParam param = new JXConfigMenusParam();
141 param.listener = null;
142 param.edge = JXConfigMenus.DEFAULT;
143 param.menuColorFore = JXTheme.getForegroundColorTheme();
144 param.rootmenu = new JMenu("Desktop", true);
145 param.options = JXTheme.WM_MENU;
146 JXConfigMenus.configMenu(param);
147 param.rootmenu.setIcon(JXLocateImage.getImageAsIcon(JXTheme.theme+"table.gif"));
148 return param.rootmenu;
149 }
150
151 /**
152 * Initialize the module.
153 * @see arch.module.JXModule
154 */
155 public JXError init(){
156 JMenuBar mbp = new JMenuBar();
157 mbp.setBorderPainted(false);
158 mbp.setPreferredSize(new Dimension(50,30));
159 dm = new JMenu();
160 dm.setPreferredSize(new Dimension(50,30));
161 dm.setIcon(JXLocateImage.getImageAsIcon(JXTheme.theme+"cup_big.gif"));
162 dm.setForeground(JXTheme.getForegroundColorTheme());
163 mbp.add(dm);
164 taskBar = new JPanel(new BorderLayout());
165 taskBar.setBorder(new SoftBevelBorder(BevelBorder.RAISED,
166 new Color(156, 153, 205), new Color(98, 101, 156)));
167 taskBar.add(mbp, BorderLayout.WEST);
168 iconManager = new JPanel(new GridLayout(1,0));
169 taskBar.add(iconManager, BorderLayout.CENTER);
170 appletManager = new JPanel(new GridLayout(1,0));
171 taskBar.add(appletManager, BorderLayout.EAST);
172 winTable = new Hashtable(40);
173 ia = new IconAction();
174 return null;
175 }
176
177 /**
178 * Facility that sets up the background of the desktop and the
179 * desktop task bar.
180 */
181 public void initBackground(){
182 pseudoRoot = new JXBackground();
183 pseudoRoot.invalidate();
184 Container c = pseudoRoot.getContentPane();
185 c.add(taskBar, BorderLayout.SOUTH);
186 taskBar.setVisible(true);
187 pseudoRoot.validate();
188 }
189
190 /**
191 * Facility provides a standardize call to restore all window states on boot up
192 * of desktop, restoring all unclosed window states during last desktop shutdown.
193 */
194 public void restoreDesktopState(){
195
196 }
197
198 /**
199 * Facility provides a way to restore saved window state.
200 * @param win
201 * the window to be restored.
202 */
203 public void restoreWindowState(JXWindow win){
204
205 }
206
207 /**
208 * Facility provides a standardize call to save all window states if a shutdown
209 * was initiated while the windows are still opened or when Window states needs
210 * to be restored on the next boot up.
211 */
212 public void saveDesktopState(){
213
214 }
215
216 /**
217 * Facility provides a way to save window state so that can be restored.
218 * @param win
219 * the window to be saved.
220 */
221 public void saveWindowState(JXWindow win){
222
223 }
224
225 /**
226 * It allows the module to do its own clean up of resources, save its
227 * states and to close the module down.
228 * @return
229 * the error that occured, if any, wrap in a JXError object. null
230 * is returned if no error occured.
231 * <dt><b>Precondition:</b><dd>
232 * The module must complete all its current task before doing a
233 * shutdown. Clients should be prepared to delay the module's
234 * shutdown process if the module indicates that it is not ready
235 * to shutdown yet through its return value.
236 * <dt><b>Postcondition:</b><dd>
237 * The module after shutdown is called cannot be used again. It
238 * should be assumed by its clients that the module no longer exist
239 * in memory and cannot be referenced anymore.
240 * @see arch.message.error.JXError
241 */
242 public JXError shutdown(){
243 if(pseudoRoot != null){
244 pseudoRoot.dispose();
245 }
246 winTable.clear();
247 return null;
248 }
249
250 /**
251 * Get a string representation of this minor module. The exact details of
252 * the representation are unspecified and subject to change, but the
253 * following maybe regarded as typical: JD4X <m7-v0.1>, [mn].
254 * It can be interpreted as module id = 7, version = 0.1 and a minor module.
255 * @return
256 * the string representation of this module with its
257 * module status.
258 * @see arch.module.JXModule
259 */
260 public String toString(){
261 StringBuffer temp = new StringBuffer(super.toString()).append(" WM");
262 return temp.toString();
263 }
264
265 /**
266 * Facility that allows any action to be taken after window is moved.
267 * @param win
268 * the event window.
269 */
270 public void windowMoved(JXWindow win){
271
272 }
273
274 /**
275 * Facility that allows any action to be taken when window is moving.
276 * @param win
277 * the event window.
278 */
279 public void windowMoving(JXWindow win){
280
281 }
282
283 /**
284 * The dafault WM merely display an icon on the task bar, so that users
285 * can click on it to deiconfy it when desired.
286 * @param win
287 * the event window.
288 */
289 public void windowIconfied(JXWindow win){
290 WindowIconSet wis = null;
291 String ine = null;
292
293 if(win == null){
294 return;
295 }
296 Long id = win.getID();
297 if(winTable.containsKey(id)){
298 synchronized(winTable){
299 wis = (WindowIconSet)winTable.get(id);
300 }
301 if(wis.icon == null){
302 ine = win.getIconName();
303 if(ine != null){
304 wis.icon = new JToggleButton(ine);
305 }
306 else{
307 wis.icon = new JToggleButton(id.toString());
308 }
309 wis.icon.addActionListener(ia);
310 iconManager.add(wis.icon);
311 /* painful Swing. */
312 iconManager.paint(iconManager.getGraphics());
313 iconManager.revalidate();
314 taskBar.paint(taskBar.getGraphics());
315 taskBar.revalidate();
316 }
317 else{
318 ine = win.getIconName();
319 if(ine != null){
320 wis.icon.setText(ine);
321 }
322 else{
323 wis.icon.setText(id.toString());
324 }
325 if(wis.icon.isSelected()){
326 wis.icon.setSelected(false);
327 wis.icon.revalidate();
328 }
329 }
330 }
331 }
332
333 /**
334 * Facility that allows any action to be taken when window is deiconfied.
335 * @param win
336 * the event window.
337 */
338 public void windowDeiconfied(JXWindow win){
339
340 }
341
342 /**
343 * Facility that allows any action to be taken when window is closed.
344 * @param win
345 * the event window.
346 */
347 public void windowClosed(JXWindow win){
348 WindowIconSet wis = null;
349
350 if(win == null){
351 return;
352 }
353 synchronized(winTable){
354 wis = (WindowIconSet)winTable.remove(win.getID());
355 }
356 if(wis != null){
357 iconManager.remove(wis.icon);
358 /* painful Swing. */
359 iconManager.paint(iconManager.getGraphics());
360 iconManager.revalidate();
361 taskBar.paint(taskBar.getGraphics());
362 taskBar.revalidate();
363 }
364 }
365
366 /**
367 * Facility that allows any action to be taken when window is closing.
368 * @param win
369 * the event window.
370 */
371 public void windowClosing(JXWindow win){
372
373 }
374
375 /**
376 * Facility that allows any action to be taken when window is opened.
377 * @param win
378 * the event window.
379 */
380 public void windowOpened(JXWindow win){
381 WindowIconSet wis = null;
382
383 if(win == null){
384 return;
385 }
386 Long id = win.getID();
387 if(!winTable.containsKey(id)){
388 wis = new WindowIconSet();
389 wis.window = win;
390 synchronized(winTable){
391 winTable.put(id, wis);
392 }
393 }
394 }
395
396 /**
397 * Facility that allows any action to be taken after window is resized.
398 * @param win
399 * the event window.
400 */
401 public void windowResized(JXWindow win){
402
403 }
404
405 /**
406 * Facility that allows any action to be taken when window is resizing.
407 * @param win
408 * the event window.
409 */
410 public void windowResizing(JXWindow win){
411
412 }
413
414 /**
415 * Facility that allows any action to be taken when window is activated.
416 * @param win
417 * the event window.
418 */
419 public void windowActivated(JXWindow win){
420
421 }
422
423 /**
424 * Facility that allows any action to be taken when window is de-activated.
425 * @param win
426 * the event window.
427 */
428 public void windowDeactivated(JXWindow win){
429
430 }
431
432 /**
433 * GUI management class to associate an icon to a window
434 * using a common ID. Direct access is used for speed.
435 */
436 protected class WindowIconSet{
437 protected JXWindow window;
438 protected JToggleButton icon;
439 }
440
441 /**
442 * Action to iconfy and deiconfy the native frame. Even though
443 * it uses linear search, it is acceptable for icon management
444 * because the number of iconifed windows are assumed to be small.
445 */
446 protected class IconAction implements ActionListener{
447 public void actionPerformed(ActionEvent ae){
448 JXTask it = null;
449 WindowIconSet wis = null;
450 Enumeration e = null;
451
452 JToggleButton tb = (JToggleButton)ae.getSource();
453 if(tb.isSelected()){
454 it = MothSupportedTask.getTaskDescription(MothSupportedTask.DEICONFY_WINDOW);
455 }
456 else{
457 it = MothSupportedTask.getTaskDescription(MothSupportedTask.ICONFY_WINDOW);
458 }
459 JXRequest[] req = new JXRequest[1];
460 synchronized(winTable){
461 e = winTable.elements();
462 }
463 for(; e.hasMoreElements() ;){
464 wis = (WindowIconSet)e.nextElement();
465 if(wis.icon == tb){
466 ((MothTask)it).setWindow(wis.window);
467 break;
468 }
469 }
470 req[0] = new JXRequest(Moth.MOTH_ID, it);
471 makeRequest(req);
472 }
473 }
474 }