KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > mrtg > client > GraphFrame


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org);
7  *
8  * (C) Copyright 2003, by Sasa Markovic.
9  *
10  * Developers: Sasa Markovic (saxon@jrobin.org)
11  * Arne Vandamme (cobralord@jrobin.org)
12  *
13  * This library is free software; you can redistribute it and/or modify it under the terms
14  * of the GNU Lesser General Public License as published by the Free Software Foundation;
15  * either version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  * See the GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License along with this
22  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  */

25
26 package org.jrobin.mrtg.client;
27
28 import org.jrobin.mrtg.MrtgException;
29
30 import javax.swing.*;
31 import javax.swing.border.BevelBorder JavaDoc;
32 import javax.swing.filechooser.FileFilter JavaDoc;
33 import java.awt.*;
34 import java.awt.event.*;
35 import java.io.BufferedOutputStream JavaDoc;
36 import java.io.File JavaDoc;
37 import java.io.FileOutputStream JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.util.Calendar JavaDoc;
40 import java.util.Date JavaDoc;
41 import java.util.GregorianCalendar JavaDoc;
42
43 class GraphFrame extends JFrame {
44
45     static final int TYPE_QUICK = 1, TYPE_DAILY = 2,
46         TYPE_WEEKLY = 3, TYPE_MONTHLY = 4, TYPE_YEARLY = 5, TYPE_CUSTOM = 6;
47     static int START_YEAR = 2000, END_YEAR = 2010;
48     static Dimension GRAPH_SIZE = new Dimension(600, 400);
49     static final int REFRESH_INTERVAL = 300; // 5 minutes
50

51     private JComboBox startDay = new JComboBox();
52     private JComboBox startMonth = new JComboBox();
53     private JComboBox startYear = new JComboBox();
54     private JComboBox startHour = new JComboBox();
55     private JComboBox endDay = new JComboBox();
56     private JComboBox endMonth = new JComboBox();
57     private JComboBox endYear = new JComboBox();
58     private JComboBox endHour = new JComboBox();
59     private JButton refreshButton= Util.largeButton("Refresh");
60     private JButton leftButton= Util.standardButton("<< Left");
61     private JButton rightButton= Util.standardButton("Right >>");
62     private JButton saveButton= Util.standardButton("Save graph...");
63     private JButton closeButton= Util.standardButton("Close");
64     private JLabel graphLabel = new JLabel();
65
66     private byte[] graphBytes;
67     private String JavaDoc mrtgHost = MrtgData.getInstance().getMrtgHost();
68     private RpcClient client;
69     private RouterInfo routerInfo;
70     private LinkInfo linkInfo;
71     private int type;
72
73     private Refresher refresher = new Refresher();
74     private JLabel infoLabel = new JLabel();
75
76     GraphFrame(JFrame parent, RouterInfo routerInfo, LinkInfo linkInfo, int type) {
77         super(linkInfo.getIfDescr() + "@" + routerInfo.getHost() + " [graph]");
78         setResizable(false);
79         this.routerInfo = routerInfo;
80         this.linkInfo = linkInfo;
81         this.type = type;
82         constructUI();
83         setInitialDates();
84         createGraph();
85         pack();
86         setVisible(true);
87     }
88
89     private void constructUI() {
90         JPanel mainContent = (JPanel) getContentPane();
91         mainContent.setLayout(new BorderLayout(3, 3));
92
93         JPanel content = new JPanel();
94         content.setLayout(new BorderLayout(3, 3));
95
96         JPanel topPanel = new JPanel();
97         topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
98         topPanel.add(new JLabel("From: "));
99         topPanel.add(startMonth);
100         topPanel.add(startDay);
101         topPanel.add(startYear);
102         topPanel.add(startHour);
103         topPanel.add(new JLabel(" To: "));
104         topPanel.add(endMonth);
105         topPanel.add(endDay);
106         topPanel.add(endYear);
107         topPanel.add(endHour);
108         if(type != TYPE_CUSTOM) {
109             startMonth.setEnabled(false);
110             startDay.setEnabled(false);
111             startYear.setEnabled(false);
112             startHour.setEnabled(false);
113             endMonth.setEnabled(false);
114             endDay.setEnabled(false);
115             endYear.setEnabled(false);
116             endHour.setEnabled(false);
117         }
118         content.add(topPanel, BorderLayout.NORTH);
119
120         // graph panel
121
graphLabel.setPreferredSize(GRAPH_SIZE);
122         graphLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
123         content.add(graphLabel, BorderLayout.CENTER);
124
125         // botom panel
126
JPanel bottomPanel = new JPanel();
127         bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
128         leftButton.addActionListener(new ActionListener() {
129             public void actionPerformed(ActionEvent e) { shift(false); }
130         });
131         if(type != TYPE_CUSTOM) {
132             bottomPanel.add(leftButton);
133         }
134         refreshButton.addActionListener(new ActionListener() {
135             public void actionPerformed(ActionEvent e) { createGraph(); }
136         });
137         bottomPanel.add(refreshButton);
138         rightButton.addActionListener(new ActionListener() {
139             public void actionPerformed(ActionEvent e) { shift(true); }
140         });
141         if(type != TYPE_CUSTOM) {
142             bottomPanel.add(rightButton);
143         }
144         content.add(bottomPanel, BorderLayout.SOUTH);
145         mainContent.add(content, BorderLayout.CENTER);
146
147         // east panel
148
Box box = Box.createVerticalBox();
149         box.add(Box.createVerticalStrut((int)topPanel.getPreferredSize().getHeight()));
150         saveButton.addActionListener(new ActionListener() {
151             public void actionPerformed(ActionEvent e) { save(); }
152         });
153         box.add(saveButton);
154         box.add(Box.createVerticalStrut(3));
155         closeButton.addActionListener(new ActionListener() {
156             public void actionPerformed(ActionEvent e) { close(); }
157         });
158         box.add(closeButton);
159         box.add(Box.createVerticalStrut(20));
160         box.add(infoLabel);
161         mainContent.add(box, BorderLayout.EAST);
162
163         // popup menu
164
final JPopupMenu popup = new JPopupMenu();
165         JMenuItem leftMenuItem = new JMenuItem("<< Left");
166         leftMenuItem.addActionListener(new ActionListener() {
167             public void actionPerformed(ActionEvent e) {
168                 shift(false);
169             }
170         });
171         JMenuItem rightMenuItem = new JMenuItem("Right >>");
172         rightMenuItem.addActionListener(new ActionListener() {
173             public void actionPerformed(ActionEvent e) {
174                 shift(true);
175             }
176         });
177         JMenuItem refreshMenuItem = new JMenuItem("Refresh graph");
178         refreshMenuItem.addActionListener(new ActionListener() {
179             public void actionPerformed(ActionEvent e) {
180                 refreshButton.doClick();
181             }
182         });
183         JMenuItem saveMenuItem = new JMenuItem("Save graph...");
184         saveMenuItem.addActionListener(new ActionListener() {
185             public void actionPerformed(ActionEvent e) {
186                 save();
187             }
188         });
189         JMenuItem closeMenuItem = new JMenuItem("Close window");
190         closeMenuItem.addActionListener(new ActionListener() {
191             public void actionPerformed(ActionEvent e) {
192                 close();
193             }
194         });
195         if(type != TYPE_CUSTOM) {
196             popup.add(leftMenuItem);
197             popup.add(rightMenuItem);
198         }
199         popup.add(refreshMenuItem);
200         popup.addSeparator();
201         popup.add(saveMenuItem);
202         popup.addSeparator();
203         popup.add(closeMenuItem);
204         MouseAdapter adapter = new MouseAdapter() {
205             public void mousePressed(MouseEvent e) { showPopup(e); }
206             public void mouseReleased(MouseEvent e) { showPopup(e); }
207             private void showPopup(MouseEvent e) {
208                 if (e.isPopupTrigger()) {
209                     popup.show(e.getComponent(), e.getX(), e.getY());
210                 }
211             }
212         };
213         graphLabel.addMouseListener(adapter);
214
215         // populate controls
216
fillDays(startDay); fillDays(endDay);
217         fillMonths(startMonth); fillMonths(endMonth);
218         fillYears(startYear); fillYears(endYear);
219         fillHours(startHour); fillHours(endHour);
220
221         addWindowListener(new WindowAdapter() {
222             public void windowClosing(WindowEvent e) {
223                 refresher.terminate();
224             }
225         });
226         getRootPane().setDefaultButton(saveButton);
227         saveButton.setMnemonic(KeyEvent.VK_S);
228         closeButton.setMnemonic(KeyEvent.VK_C);
229         refreshButton.setMnemonic(KeyEvent.VK_F);
230         leftButton.setMnemonic(KeyEvent.VK_L);
231         rightButton.setMnemonic(KeyEvent.VK_R);
232         setDefaultCloseOperation(DISPOSE_ON_CLOSE);
233         try {
234             setIconImage(Resources.getImage(Client.ICON));
235         } catch (MrtgException e) {
236             e.printStackTrace();
237         }
238         Util.centerOnScreen(this);
239     }
240
241     private void close() {
242         dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
243     }
244
245     private void save() {
246         if(graphBytes == null) {
247             return;
248         }
249         JFileChooser chooser = new JFileChooser();
250         FileFilter JavaDoc filter = new FileFilter JavaDoc() {
251             public boolean accept(File JavaDoc f) {
252                 return f.isDirectory()? true:
253                     f.getAbsolutePath().toLowerCase().endsWith(".png");
254             }
255             public String JavaDoc getDescription() {
256                 return "PNG images";
257             }
258         };
259         chooser.setFileFilter(filter);
260         int returnVal = chooser.showSaveDialog(this);
261         if(returnVal == JFileChooser.APPROVE_OPTION) {
262             try {
263                 File JavaDoc selectedFile = chooser.getSelectedFile();
264                 String JavaDoc path = selectedFile.getAbsolutePath();
265                 if(!path.toLowerCase().endsWith(".png")) {
266                     path += ".png";
267                     selectedFile = new File JavaDoc(path);
268                 }
269                 if(selectedFile.exists()) {
270                     // ask user to overwrite
271
String JavaDoc message = "File [" + selectedFile.getName() +
272                         "] already exists. Do you want to overwrite it?";
273                     int answer = JOptionPane.showConfirmDialog(this,
274                         message, "File exists", JOptionPane.YES_NO_OPTION);
275                     if(answer == JOptionPane.NO_OPTION) {
276                         return;
277                     }
278                 }
279                 BufferedOutputStream JavaDoc out = new BufferedOutputStream JavaDoc(
280                     new FileOutputStream JavaDoc(selectedFile));
281                 out.write(graphBytes);
282                 out.close();
283             } catch (IOException JavaDoc e) {
284                 Util.error(this, "Could not save graph to file:\n" + e);
285             }
286         }
287     }
288
289     private void shift(boolean right) {
290         int sign = right? +1: -1;
291         GregorianCalendar JavaDoc start = getDate(false);
292         GregorianCalendar JavaDoc end = getDate(true);
293         switch(type) {
294             case TYPE_QUICK:
295             case TYPE_DAILY:
296                 start.add(Calendar.DAY_OF_MONTH, sign * 1);
297                 end.add(Calendar.DAY_OF_MONTH, sign * 1);
298                 break;
299             case TYPE_WEEKLY:
300                 start.add(Calendar.DAY_OF_MONTH, sign * 7);
301                 end.add(Calendar.DAY_OF_MONTH, sign * 7);
302                 break;
303             case TYPE_MONTHLY:
304                 start.add(Calendar.MONTH, sign * 1);
305                 end.add(Calendar.MONTH, sign * 1);
306                 break;
307             case TYPE_YEARLY:
308                 start.add(Calendar.YEAR, sign * 1);
309                 end.add(Calendar.YEAR, sign * 1);
310                 break;
311         }
312         setDate(start, false);
313         setDate(end, true);
314         createGraph();
315     }
316
317     private void createGraph() {
318         refresher.terminate();
319         refreshButton.setText("Refresh");
320         Date JavaDoc start = getDate(false).getTime();
321         Date JavaDoc end = getDate(true).getTime();
322         Date JavaDoc now = new Date JavaDoc();
323         if(start.getTime() >= end.getTime()) {
324             Util.error(this, "Invalid time span");
325             return;
326         }
327         try {
328             if(client == null) {
329                 client = new RpcClient(mrtgHost);
330             }
331             graphBytes = client.getPngGraph(routerInfo, linkInfo, start, end);
332             ImageIcon icon = new ImageIcon(graphBytes, "PNG graph");
333             if(icon.getIconWidth() != GRAPH_SIZE.getWidth() ||
334                     icon.getIconHeight() != GRAPH_SIZE.getHeight()) {
335                 GRAPH_SIZE = new Dimension(icon.getIconWidth(), icon.getIconHeight());
336                 graphLabel.setPreferredSize(GRAPH_SIZE);
337                 pack();
338             }
339             graphLabel.setIcon(icon);
340             if(start.getTime() <= now.getTime() && now.getTime() < end.getTime()) {
341                 refresher = new Refresher();
342                 refresher.start();
343             }
344         } catch (Exception JavaDoc e) {
345             Util.error(this, "Graph could not be generated:\n" + e);
346         }
347     }
348
349     private GregorianCalendar JavaDoc getDate(boolean isEnd) {
350         JComboBox hourCombo = isEnd? endHour: startHour;
351         JComboBox dayCombo = isEnd? endDay: startDay;
352         JComboBox monthCombo = isEnd? endMonth: startMonth;
353         JComboBox yearCombo = isEnd? endYear: startYear;
354         int hour = hourCombo.getSelectedIndex();
355         int day = dayCombo.getSelectedIndex() + 1;
356         int month = monthCombo.getSelectedIndex();
357         int year = yearCombo.getSelectedIndex() + START_YEAR;
358         return new GregorianCalendar JavaDoc(year, month, day, hour, 0);
359     }
360
361     private void fillDays(JComboBox combo) {
362         for(int i = 1; i <= 31; i++) {
363             combo.insertItemAt((i < 10? "0": "") + i, i - 1);
364         }
365         combo.setSelectedIndex(0);
366     }
367
368     private void fillMonths(JComboBox combo) {
369         String JavaDoc names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Avg", "Sep",
370                            "Oct", "Nov", "Dec" };
371         for(int i = 0; i < names.length; i++) {
372             combo.insertItemAt(names[i], i);
373         }
374         combo.setSelectedIndex(0);
375     }
376
377     private void fillYears(JComboBox combo) {
378         for(int i = START_YEAR; i <= END_YEAR; i++) {
379             combo.insertItemAt("" + i, i - START_YEAR);
380         }
381         combo.setSelectedIndex(0);
382     }
383
384     private void fillHours(JComboBox combo) {
385         for(int i = 0; i < 24; i++) {
386             String JavaDoc str = (i < 10? "0": "") + i + ":00";
387             combo.insertItemAt(str, i);
388         }
389         combo.setSelectedIndex(0);
390     }
391
392     private void setDate(GregorianCalendar JavaDoc gc, boolean isEnd) {
393         JComboBox hourCombo = isEnd? endHour: startHour;
394         JComboBox dayCombo = isEnd? endDay: startDay;
395         JComboBox monthCombo = isEnd? endMonth: startMonth;
396         JComboBox yearCombo = isEnd? endYear: startYear;
397         hourCombo.setSelectedIndex(gc.get(Calendar.HOUR_OF_DAY));
398         dayCombo.setSelectedIndex(gc.get(Calendar.DAY_OF_MONTH) - 1);
399         monthCombo.setSelectedIndex(gc.get(Calendar.MONTH));
400         yearCombo.setSelectedIndex(gc.get(Calendar.YEAR) - START_YEAR);
401     }
402
403     private void setInitialDates() {
404         GregorianCalendar JavaDoc start = null, end = null, gc = new GregorianCalendar JavaDoc();
405         switch(type) {
406             case TYPE_QUICK:
407                 start = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH),
408                     gc.get(Calendar.DAY_OF_MONTH) - 1, gc.get(Calendar.HOUR_OF_DAY) + 1, 0);
409                 end = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH),
410                     gc.get(Calendar.DAY_OF_MONTH), gc.get(Calendar.HOUR_OF_DAY) + 1, 0);
411                 break;
412             case TYPE_DAILY:
413             case TYPE_CUSTOM:
414                 start = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR),
415                     gc.get(Calendar.MONTH), gc.get(Calendar.DAY_OF_MONTH));
416                 end = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR),
417                     gc.get(Calendar.MONTH), gc.get(Calendar.DAY_OF_MONTH) + 1);
418                 break;
419             case TYPE_WEEKLY:
420                 int shift = gc.get(Calendar.DAY_OF_WEEK) - 1;
421                 start = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH),
422                     gc.get(Calendar.DAY_OF_MONTH) - shift);
423                 end = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH),
424                     gc.get(Calendar.DAY_OF_MONTH) - shift + 7);
425                 break;
426             case TYPE_MONTHLY:
427                 start = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR),
428                     gc.get(Calendar.MONTH), 1);
429                 end = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR),
430                     gc.get(Calendar.MONTH) + 1, 1);
431                 break;
432             case TYPE_YEARLY:
433                 start = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR), 0, 1);
434                 end = new GregorianCalendar JavaDoc(gc.get(Calendar.YEAR) + 1, 0, 1);
435                 break;
436         }
437         setDate(start, false);
438         setDate(end, true);
439     }
440
441     class Refresher extends Thread JavaDoc {
442         private boolean active = true;
443         private int secs = REFRESH_INTERVAL;
444
445         Refresher() {
446             setDaemon(true);
447         }
448
449         public void run() {
450             while(active) {
451                 for(secs = REFRESH_INTERVAL; secs >= 0 && active; secs--) {
452                     refreshButton.setText("Refreshing in " + secs + '"');
453                     try {
454                         sleep(1000L);
455                     }
456                     catch (InterruptedException JavaDoc e) { }
457                 }
458                 if(active) {
459                     refreshButton.doClick();
460                 }
461             }
462         }
463
464         void terminate() {
465             active = false;
466         }
467
468         void reset() {
469             secs = REFRESH_INTERVAL;
470         }
471     }
472 }
473
Popular Tags