1 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 ; 32 import javax.swing.filechooser.FileFilter ; 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.io.BufferedOutputStream ; 36 import java.io.File ; 37 import java.io.FileOutputStream ; 38 import java.io.IOException ; 39 import java.util.Calendar ; 40 import java.util.Date ; 41 import java.util.GregorianCalendar ; 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; 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 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 graphLabel.setPreferredSize(GRAPH_SIZE); 122 graphLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); 123 content.add(graphLabel, BorderLayout.CENTER); 124 125 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 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 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 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 filter = new FileFilter () { 251 public boolean accept(File f) { 252 return f.isDirectory()? true: 253 f.getAbsolutePath().toLowerCase().endsWith(".png"); 254 } 255 public String 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 selectedFile = chooser.getSelectedFile(); 264 String path = selectedFile.getAbsolutePath(); 265 if(!path.toLowerCase().endsWith(".png")) { 266 path += ".png"; 267 selectedFile = new File (path); 268 } 269 if(selectedFile.exists()) { 270 String 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 out = new BufferedOutputStream ( 280 new FileOutputStream (selectedFile)); 281 out.write(graphBytes); 282 out.close(); 283 } catch (IOException 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 start = getDate(false); 292 GregorianCalendar 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 start = getDate(false).getTime(); 321 Date end = getDate(true).getTime(); 322 Date now = new Date (); 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 e) { 345 Util.error(this, "Graph could not be generated:\n" + e); 346 } 347 } 348 349 private GregorianCalendar 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 (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 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 str = (i < 10? "0": "") + i + ":00"; 387 combo.insertItemAt(str, i); 388 } 389 combo.setSelectedIndex(0); 390 } 391 392 private void setDate(GregorianCalendar 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 start = null, end = null, gc = new GregorianCalendar (); 405 switch(type) { 406 case TYPE_QUICK: 407 start = new GregorianCalendar (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 (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 (gc.get(Calendar.YEAR), 415 gc.get(Calendar.MONTH), gc.get(Calendar.DAY_OF_MONTH)); 416 end = new GregorianCalendar (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 (gc.get(Calendar.YEAR), gc.get(Calendar.MONTH), 422 gc.get(Calendar.DAY_OF_MONTH) - shift); 423 end = new GregorianCalendar (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 (gc.get(Calendar.YEAR), 428 gc.get(Calendar.MONTH), 1); 429 end = new GregorianCalendar (gc.get(Calendar.YEAR), 430 gc.get(Calendar.MONTH) + 1, 1); 431 break; 432 case TYPE_YEARLY: 433 start = new GregorianCalendar (gc.get(Calendar.YEAR), 0, 1); 434 end = new GregorianCalendar (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 { 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 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 |