Source code: dexter/core/MainFrame.java
1 /*
2 This file is part of DeXter - Java Internet Communication Solution
3 Copyright (c) 2002 Tobias Riemer
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 package dexter.core;
21
22 import dexter.swingExtensions.Trayable;
23 import java.util.Collection;
24 import java.awt.Dimension;
25 import java.util.Iterator;
26 import java.awt.BorderLayout;
27 import javax.swing.*;
28 import dexter.events.ActionListener;
29
30
31 /**
32 *
33 * @author Tobias Riemer
34 */
35 public class MainFrame extends javax.swing.JFrame {
36
37 private dexter.swingExtensions.TrayPanel tray = new dexter.swingExtensions.TrayPanel();
38 private JPanel jServicePanel = new dexter.core.MainFrame.ScrollPanePanel();
39
40 private Action aboutAction;
41 private Action preferencesAction = new dexter.core.MainFrame.PreferencesAction();
42 private java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
43 private java.util.HashMap mainMenu = new java.util.HashMap();
44
45 private javax.swing.JScrollPane sp;
46 private JPanel spPanel = new JPanel(new BorderLayout());
47 /** Creates new form ContactListFrame */
48 public MainFrame() {
49
50 // @todo Create an about Dialog - not in this Version
51 aboutAction = new dexter.core.MainFrame.AboutAction(this);
52
53 initComponents();
54
55 mainMenu.put("", jMenuBar1);
56 mainMenu.put(".HELP", jMenu2);
57 mainMenu.put(".OPTIONS", jMenu1);
58 mainMenu.put(".OPTIONS.PLUGINS", jMenu3);
59
60 setIconImage(Dexter.getInstance().getIcon().getImage());
61 jPanel1.add(tray,BorderLayout.EAST);
62
63 sp = new javax.swing.JScrollPane( jServicePanel );
64 //sp.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
65 jServicePanel.setLayout(new dexter.swingExtensions.PanelLayout());
66
67 sp.setPreferredSize(new Dimension(270, 370));
68
69 spPanel.add(sp,BorderLayout.CENTER);
70 getContentPane().add(spPanel, BorderLayout.CENTER);
71
72 jPanel1.setBackground(Dexter.getInstance().getMainColor());
73
74 jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(Dexter.getInstance().getMainColor()));
75 tray.setOpaque(false);
76 jPanel2.setOpaque(false);
77 Dexter.getInstance().getEventDispatcher().addActionListener("MainFrame.show", new ActionListener() {
78 public void actionPerformed(dexter.events.Event event) {
79 setVisible(true);
80 toFront();
81 }
82 });
83 Dexter.getInstance().getEventDispatcher().addActionListener("MainFrame.hide", new ActionListener() {
84 public void actionPerformed(dexter.events.Event event) {
85 setVisible(false);
86 toFront();
87 }
88 });
89
90 setBgColor();
91 }
92
93
94 /** This method is called from within the constructor to
95 * initialize the form.
96 * WARNING: Do NOT modify this code. The content of this method is
97 * always regenerated by the Form Editor.
98 */
99 private void initComponents() {//GEN-BEGIN:initComponents
100 jPanel1 = new dexter.swingExtensions.TPanel();
101 jPanel2 = new javax.swing.JPanel();
102 jMenuBar1 = new javax.swing.JMenuBar();
103 jMenu1 = new javax.swing.JMenu();
104 jMenuItem1 = new javax.swing.JMenuItem();
105 jMenu3 = new javax.swing.JMenu();
106 jMenu2 = new javax.swing.JMenu();
107 jMenuItem2 = new javax.swing.JMenuItem();
108
109 setTitle("Dexter");
110 setIconImage(new javax.swing.ImageIcon(getClass().getResource("/dexter/images/icon.gif")).getImage());
111 addWindowListener(new java.awt.event.WindowAdapter() {
112 public void windowClosing(java.awt.event.WindowEvent evt) {
113 exitForm(evt);
114 }
115 });
116
117 jPanel1.setLayout(new java.awt.BorderLayout());
118
119 jPanel1.add(jPanel2, java.awt.BorderLayout.CENTER);
120
121 getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);
122
123 jMenu1.setMnemonic('p');
124 jMenu1.setText("Options");
125 jMenu1.setName("OPTIONS");
126 jMenuItem1.setMnemonic('P');
127 jMenuItem1.setAction(preferencesAction);
128 jMenu1.add(jMenuItem1);
129 jMenu3.setMnemonic('l');
130 jMenu3.setText("Plugins");
131 jMenu3.setName("PLUGINS");
132 jMenu1.add(jMenu3);
133 jMenuBar1.add(jMenu1);
134 jMenu2.setMnemonic('H');
135 jMenu2.setText("Help");
136 jMenu2.setName("HELP");
137 jMenuItem2.setAction(aboutAction);
138 jMenu2.add(jMenuItem2);
139 jMenuBar1.add(jMenu2);
140 setJMenuBar(jMenuBar1);
141
142 pack();
143 }//GEN-END:initComponents
144
145 private void propBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_propBtnActionPerformed
146 // Add your handling code here:
147
148 }//GEN-LAST:event_propBtnActionPerformed
149
150
151 public void updateUI() {
152 System.out.println("UPDATEUI");
153 setBgColor();
154 Collection col = Dexter.getInstance().getServices().values();
155 Iterator it = col.iterator();
156 while(it.hasNext()) {
157 System.out.println("updateui");
158 Service s = (Service) it.next();
159 s.updateUI();
160 }
161
162 }
163
164 private void setBgColor() {
165 /*java.awt.Color color = Dexter.resourceFactory().getColor("dexter","DEXTERBG");
166 if (color != null) {
167 jServicePanel.setBackground(color);
168 }*/
169 }
170
171 /** Exit the Application */
172 private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
173 if (Dexter.trayIcon)
174 setVisible(false);
175 else {
176 stopServices();
177 System.exit(0);
178 }
179 }//GEN-LAST:event_exitForm
180
181 public void stopServices() {
182
183 Collection col = Dexter.getInstance().getServices().values();
184 Iterator it = col.iterator();
185 while(it.hasNext()) {
186 Service s = (Service) it.next();
187 s.destroy();
188 }
189 try {
190 while(!checkAllServicesStopped()) {
191 Thread.sleep(100);
192 }
193 } catch (Exception ex) {}
194 System.exit(0);
195 }
196
197 private boolean checkAllServicesStopped() {
198 boolean allstopped = true;
199 Collection col = Dexter.getInstance().getServices().values();
200 Iterator it = col.iterator();
201 while(it.hasNext()) {
202 Service s = (Service) it.next();
203 if (!s.isDestroyed()) {
204 allstopped = false;
205 }
206 }
207 return allstopped;
208 }
209
210 // Variables declaration - do not modify//GEN-BEGIN:variables
211 private javax.swing.JMenuItem jMenuItem2;
212 private javax.swing.JMenu jMenu2;
213 private javax.swing.JPanel jPanel2;
214 private javax.swing.JMenuItem jMenuItem1;
215 private javax.swing.JMenu jMenu3;
216 private javax.swing.JPanel jPanel1;
217 private javax.swing.JMenu jMenu1;
218 private javax.swing.JMenuBar jMenuBar1;
219 // End of variables declaration//GEN-END:variables
220
221
222 public void addTrayIcon(Trayable e) {
223 tray.addTrayIcon(e);
224 }
225
226 public void removeTrayIcon(Trayable e) {
227 tray.removeTrayIcon(e);
228 }
229
230 public void reorderPanels() {
231 jServicePanel.removeAll();
232 java.util.Vector serviceStrings = Dexter.getInstance().getServiceStrings();
233 java.util.HashMap services = Dexter.getInstance().getServices();
234 for(int i=0;i<serviceStrings.size();i++) {
235 ServiceName sn = new ServiceName(((String) serviceStrings.get(i)));
236 Service s = (Service) services.get(sn.getId());;
237 //System.out.println(((String) serviceStrings.get(i)));
238 if (s.getPanel() != null) jServicePanel.add(s.getPanel());
239 }
240 jServicePanel.revalidate();
241 }
242
243 public void addService(Service s) {
244 s.addTrayListener(tray);
245 if (s instanceof Trayable)
246 if ( ((Trayable) s).isTray()) addTrayIcon((Trayable) s);
247 if (s.getPanel() != null) jServicePanel.add(s.getPanel());
248 System.out.println("CREATING MENU");
249 includePluginMenu(s.getPluginMenu(), jMenuBar1);
250 this.setJMenuBar(jMenuBar1);
251 }
252
253 private void includePluginMenu(PluginMenu pm, java.awt.Component parentMenu) {
254 for(int i=0;i<pm.size();i++) {
255
256 if (pm.get(i) instanceof PluginMenu) {
257 System.out.println("PLUGINMENU--> " + pm.get(i));
258 JMenu menu = (JMenu) mainMenu.get(pm.get(i).toString());
259 if (menu == null) menu = createNewMenuEntry(parentMenu, (PluginMenu) pm.get(i));
260 includePluginMenu((PluginMenu) pm.get(i), menu);
261 } else {
262 if (pm.get(i) instanceof Action) {
263 System.out.println("ACTION--> " + pm.get(i));
264 createNewMenuEntry(parentMenu, (Action) pm.get(i));
265 }
266 }
267 }
268 }
269
270 private JMenu createNewMenuEntry(java.awt.Component parentMenu, PluginMenu pm) {
271 System.out.println("create menu: " + pm.getName());
272 JMenu menu = new JMenu(pm.getName());
273 mainMenu.put(pm.toString(),menu);
274 if (parentMenu instanceof JMenuBar) ((JMenuBar) parentMenu).add(menu);
275 if (parentMenu instanceof JMenu) ((JMenu) parentMenu).add(menu);
276 return menu;
277 }
278
279 private javax.swing.JMenuItem createNewMenuEntry(java.awt.Component parentMenu, Action action) {
280 javax.swing.JMenuItem menuItem = new javax.swing.JMenuItem(action);
281 if (parentMenu instanceof JMenuBar) ((JMenuBar) parentMenu).add(menuItem);
282 if (parentMenu instanceof JMenu) ((JMenu) parentMenu).add(menuItem);
283 return menuItem;
284 }
285
286 public void removeService(Service s) {
287 s.destroy();
288 if (s instanceof Trayable)
289 if ( ((Trayable) s).isTray()) removeTrayIcon((Trayable) s);
290 jServicePanel.remove(s.getPanel());
291 }
292
293 public void changeTrayIcon(Trayable e) {
294 tray.changeTrayIcon(e);
295 }
296
297 public void showMsgBox(String text) {
298 javax.swing.JOptionPane.showMessageDialog(null,
299 text,
300 "Warning Message",
301 javax.swing.JOptionPane.INFORMATION_MESSAGE);
302 }
303
304 public void showPropertiesDlg() {
305 new dexter.property.PropertiesDlg(this, Dexter.getInstance().getPropertyFile()).show();
306 }
307
308 public class PreferencesAction extends javax.swing.AbstractAction {
309
310 /**
311 * @todo Provide an Icon for Send
312 */
313 public PreferencesAction() {
314 super("Preferences");
315 }
316
317 /** Invoked when an action occurs.
318 */
319 public void actionPerformed(java.awt.event.ActionEvent e) {
320 showPropertiesDlg();
321 }
322 }
323
324 public class AboutAction extends javax.swing.AbstractAction {
325
326 private javax.swing.JFrame parent;
327
328 /**
329 * @todo Provide an Icon for Send
330 */
331 public AboutAction(javax.swing.JFrame parent) {
332 super("About");
333 this.parent = parent;
334
335 this.putValue(Action.MNEMONIC_KEY, new Integer('A'));
336 }
337
338 /** Invoked when an action occurs.
339 */
340 public void actionPerformed(java.awt.event.ActionEvent e) {
341 JAboutBox aboutBox = new JAboutBox(parent, false);
342 aboutBox.show();
343 }
344 }
345
346 public void minimizeAllbut(Trayable max) {
347 Collection col = Dexter.getInstance().getServices().values();
348 Iterator it = col.iterator();
349 while(it.hasNext()) {
350 Service s = (Service) it.next();
351 if (s instanceof Trayable) {
352 if (s != max) ((Trayable) s).sendToTray();
353 }
354 }
355 }
356
357 class ScrollPanePanel extends JPanel implements javax.swing.Scrollable {
358 public ScrollPanePanel() {
359 };
360
361 public Dimension getPreferredSize() {
362 Dimension pSize = super.getPreferredSize();
363 pSize.width = spPanel.getSize().width;
364 return pSize;
365 }
366
367 /** Returns the preferred size of the viewport for a view component.
368 * For example the preferredSize of a JList component is the size
369 * required to accommodate all of the cells in its list however the
370 * value of preferredScrollableViewportSize is the size required for
371 * JList.getVisibleRowCount() rows. A component without any properties
372 * that would effect the viewport size should just return
373 * getPreferredSize() here.
374 *
375 * @return The preferredSize of a JViewport whose view is this Scrollable.
376 * @see JViewport#getPreferredSize
377 */
378 public Dimension getPreferredScrollableViewportSize() {
379 return getPreferredSize();
380 }
381
382 /** Components that display logical rows or columns should compute
383 * the scroll increment that will completely expose one block
384 * of rows or columns, depending on the value of orientation.
385 * <p>
386 * Scrolling containers, like JScrollPane, will use this method
387 * each time the user requests a block scroll.
388 *
389 * @param visibleRect The view area visible within the viewport
390 * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
391 * @param direction Less than zero to scroll up/left, greater than zero for down/right.
392 * @return The "block" increment for scrolling in the specified direction.
393 * This value should always be positive.
394 * @see JScrollBar#setBlockIncrement
395 */
396 public int getScrollableBlockIncrement(java.awt.Rectangle visibleRect, int orientation, int direction) {
397 return 20;
398 }
399
400 /** Return true if a viewport should always force the height of this
401 * Scrollable to match the height of the viewport. For example a
402 * columnar text view that flowed text in left to right columns
403 * could effectively disable vertical scrolling by returning
404 * true here.
405 * <p>
406 * Scrolling containers, like JViewport, will use this method each
407 * time they are validated.
408 *
409 * @return True if a viewport should force the Scrollables height to match its own.
410 */
411 public boolean getScrollableTracksViewportHeight() {
412 return false;
413 }
414
415 /** Return true if a viewport should always force the width of this
416 * <code>Scrollable</code> to match the width of the viewport.
417 * For example a normal
418 * text view that supported line wrapping would return true here, since it
419 * would be undesirable for wrapped lines to disappear beyond the right
420 * edge of the viewport. Note that returning true for a Scrollable
421 * whose ancestor is a JScrollPane effectively disables horizontal
422 * scrolling.
423 * <p>
424 * Scrolling containers, like JViewport, will use this method each
425 * time they are validated.
426 *
427 * @return True if a viewport should force the Scrollables width to match its own.
428 */
429 public boolean getScrollableTracksViewportWidth() {
430 return true;
431 }
432
433 /** Components that display logical rows or columns should compute
434 * the scroll increment that will completely expose one new row
435 * or column, depending on the value of orientation. Ideally,
436 * components should handle a partially exposed row or column by
437 * returning the distance required to completely expose the item.
438 * <p>
439 * Scrolling containers, like JScrollPane, will use this method
440 * each time the user requests a unit scroll.
441 *
442 * @param visibleRect The view area visible within the viewport
443 * @param orientation Either SwingConstants.VERTICAL or SwingConstants.HORIZONTAL.
444 * @param direction Less than zero to scroll up/left, greater than zero for down/right.
445 * @return The "unit" increment for scrolling in the specified direction.
446 * This value should always be positive.
447 * @see JScrollBar#setUnitIncrement
448 */
449 public int getScrollableUnitIncrement(java.awt.Rectangle visibleRect, int orientation, int direction) {
450 return 20;
451 }
452
453 }
454
455 }