Package ch.rakudave.NetMap

Source Code of ch.rakudave.NetMap.NetMap

/*      jNetMap
*     
*      Created by rakudave <public@rakudave.ch>
*     
*      This program is free software; you can redistribute it and/or modify
*      it under the terms of the GNU General Public License as published by
*      the Free Software Foundation; either version 3 of the License, or
*      (at your option) any later version.
*     
*      This program is distributed in the hope that it will be useful,
*      but WITHOUT ANY WARRANTY; without even the implied warranty of
*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*      GNU General Public License for more details.
*/

package ch.rakudave.NetMap;

import java.awt.AWTException;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.MenuItem;
import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.filechooser.FileNameExtensionFilter;

public class NetMap implements Runnable {
  private JButton check;
  private JProgressBar progress;
  private JMenu recent;
  private Thread t;
  protected NetCanvas canvas;
  protected JFrame f;
  protected JTextField interval;
  protected Vector<String> recentFiles;
  protected String currentFile, password;
  protected Preferences preferences;
  protected Triggers triggers;
  protected JMenuItem connect, disconnect, remove, settings, undo, redo;
  protected JCheckBox showGrid, showLegend, showStats;
  protected TrayIcon trayIcon;
  protected final String version = "0.3.3.5";

  public static void main(String[] args) {
    new NetMap(args);
  }

  /**
   * Create new jNetMap instance
   *
   * @param args command line arguments such as file to open
   */
  public NetMap(final String[] args) {
    preferences = new Preferences(this);
    canvas = new NetCanvas(this, preferences);
    check = new JButton("check now");
    progress = new JProgressBar();
    recent = new JMenu("Recent Files");
    javax.swing.SwingUtilities.invokeLater(new Runnable() {public void run() {createGUI(args);}});
    t = new Thread(this);
    t.start();
    Updater.checkForUpdates(this);
  }

  // create main window
  private void createGUI(String[] args) {
    f = new JFrame("jNetMap");
    f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // let me handle that (ask to save)
    f.setPreferredSize(new Dimension(800,700));
    f.add(canvas);
    // build the menu
    JMenuBar menu = new JMenuBar();
      JMenu file = new JMenu("File");
        JMenuItem newFile = new JMenuItem("New");
          newFile.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N,java.awt.Event.CTRL_MASK));
          newFile.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {newFile();}});
        JMenuItem open = new JMenuItem("Open");
          open.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O,java.awt.Event.CTRL_MASK));
          open.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {openFile(null);}});
        JMenuItem save = new JMenuItem("Save");
          save.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S,java.awt.Event.CTRL_MASK));
          save.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {saveFile(currentFile);}});
        JMenuItem saveas = new JMenuItem("Save As...");
          saveas.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S,java.awt.Event.CTRL_MASK+java.awt.Event.SHIFT_MASK));
          saveas.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {saveFile(null);}});
        JMenuItem protect = new JMenuItem("Protect");
          protect.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {newPassword();}});
        JMenuItem export = new JMenuItem("Export Image");
          export.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E,java.awt.Event.CTRL_MASK));
          export.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {imageExport();}});
        JMenuItem exit = new JMenuItem("Exit");
          exit.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q,java.awt.Event.CTRL_MASK));
          exit.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {destroy();}});
        file.add(newFile);
        file.add(open);
        file.add(recent);
        file.add(new JSeparator());
        file.add(save);
        file.add(saveas);
        file.add(protect);
        file.add(new JSeparator());
        file.add(export);
        file.add(new JSeparator());
        file.add(exit);
      JMenu edit = new JMenu("Edit");
        JMenuItem addItem = new JMenuItem("Add Device");
          addItem.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A,java.awt.Event.CTRL_MASK));
          addItem.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.addItem(null);}});
        JMenuItem addNote = new JMenuItem("Add Note");
          addNote.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N,java.awt.Event.CTRL_MASK));
          addNote.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {NetNote note = new NetNote("","",new Point(50,50)); canvas.notes.add(note); canvas.editNote(note);}});
        undo = new JMenuItem("Undo");
          undo.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z,java.awt.Event.CTRL_MASK));
          undo.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.undo();}});
          undo.setEnabled(false);
        redo = new JMenuItem("Redo");
          redo.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Y,java.awt.Event.CTRL_MASK));
          redo.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.redo();}});
          redo.setEnabled(false);
        connect = new JMenuItem("Connect");
          connect.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SPACE, 0));
          connect.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.connect();}});
          connect.setEnabled(false);
        disconnect = new JMenuItem("Disconnect");
          disconnect.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE, 0));
          disconnect.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.disconnect();}});
          disconnect.setEnabled(false);
        remove = new JMenuItem("Remove");
          remove.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0));
          remove.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.remove();}});
          remove.setEnabled(false);
        settings = new JMenuItem("Settings");
          settings.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0));
          settings.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.settings();}});
          settings.setEnabled(false);
        JMenuItem bg = new JMenuItem("Add Background Image");
          bg.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_B,java.awt.Event.CTRL_MASK));
          bg.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {BackgroundImage img = new BackgroundImage(canvas); if (img.getPath() != null) canvas.backgroundImages.add(img);canvas.repaint();}});
        JMenuItem rmbg = new JMenuItem("Remove All BG Images");
          rmbg.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.backgroundImages.clear();canvas.repaint();canvas.updateHistory();}});
        JMenuItem scan = new JMenuItem("Scan for Devices");
          scan.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F,java.awt.Event.CTRL_MASK));
          scan.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {new NetScan(canvas);}});
        edit.add(addItem);
        edit.add(addNote);
        edit.add(new JSeparator());
        edit.add(undo);
        edit.add(redo);
        edit.add(new JSeparator());
        edit.add(connect);
        edit.add(disconnect);
        edit.add(remove);
        edit.add(settings);
        edit.add(new JSeparator());
        edit.add(bg);
        edit.add(rmbg);
        edit.add(new JSeparator());
        edit.add(scan);
      JMenu view = new JMenu("View");
        showGrid = new JCheckBox("Grid Mode", preferences.drawGrid);
          showGrid.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {preferences.drawGrid = !preferences.drawGrid; canvas.repaint();}});
        JMenuItem align = new JMenuItem("Align to Grid");
          align.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_G,java.awt.Event.CTRL_MASK));
          align.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.alignToGrid(null);}});
        showLegend = new JCheckBox("Show Legend", preferences.drawLegend);
          showLegend.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {preferences.drawLegend = !preferences.drawLegend; canvas.repaint();}});
        showStats = new JCheckBox("Show Statistics", preferences.drawStats);
          showStats.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {preferences.drawStats = !preferences.drawStats; canvas.repaint();}});
        view.add(showGrid);
        view.add(align);
        view.add(new JSeparator());
        view.add(showLegend);
        view.add(showStats);
      JMenu tools = new JMenu("Tools");
        JMenuItem scanner = new JMenuItem("Port Scanner");
          scanner.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_P,java.awt.Event.CTRL_MASK));
          scanner.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {if (canvas.selected.size() > 0) new PortProbe(canvas.selected.get(0).getIP()); else new PortProbe("127.0.0.1");}});
        JMenuItem checkNow = new JMenuItem("Check Now");
          checkNow.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X,java.awt.Event.CTRL_MASK));
          checkNow.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {t.interrupt();}});
        JMenuItem resetCanvas = new JMenuItem("Reset Canvas");
          resetCanvas.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R,java.awt.Event.CTRL_MASK));
          resetCanvas.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {canvas.resetCanvas();}});
        JMenuItem prefs = new JMenuItem("Preferences");
          prefs.setAccelerator(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_COMMA,java.awt.Event.CTRL_MASK));
          prefs.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {preferences.showDialog();}});
        tools.add(scanner);
        tools.add(checkNow);
        tools.add(resetCanvas);
        tools.add(new JSeparator());
        tools.add(prefs);
      JMenu help = new JMenu("Help");
        JMenuItem web = new JMenuItem("Documentation");
          web.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {openURL("http://www.rakudave.ch/jnetmap#download");}});
        JMenuItem bug = new JMenuItem("Report a Bug");
          bug.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {showBugs();}});
        JMenuItem about = new JMenuItem("About");
          about.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {showAbout();}});
        help.add(web);
        help.add(bug);
        help.add(new JSeparator());
        help.add(about);
      interval = new JTextField(preferences.pingInterval+"");
        interval.setMaximumSize(new Dimension(30,20));
        interval.setPreferredSize(new Dimension(30,20));
        interval.setToolTipText("Floats are Ok");
      check.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {t.interrupt();}});
      check.setPreferredSize(new Dimension(100,20));
      progress.setMaximumSize(new Dimension(100,20));
      progress.setPreferredSize(new Dimension(100,20));
      progress.setStringPainted(true);
      progress.setVisible(false);
      menu.add(file);
      menu.add(edit);
      menu.add(view);
      menu.add(tools);
      menu.add(help);
      menu.add(Box.createHorizontalGlue());
      menu.add(new JLabel("Ping interval: "));
      menu.add(interval);
      menu.add(new JLabel(" min "));
      menu.add(check);
      menu.add(progress);
      menu.add(Box.createHorizontalStrut(5));
    f.setJMenuBar(menu);
    // done building menu
    f.setIconImage(Icon.OTHER.getImage());
    f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent evt) {destroy();}});
    f.pack();
    if (preferences.rememberSize) f.setSize(preferences.windowSize);
    if (preferences.rememberPosition) f.setLocation(preferences.windowPosition);
    f.setVisible(true);
    onLaunch(args);
    addTrayIcon();
    t.interrupt();
  }

  // infinite loop during runtime, ping all hosts, then sleep for x seconds
  public void run() {
    while (true) {
      try {
        try { // sleep for (one minute * the interval)
          if (preferences.pingInterval <= 0) synchronized (t) {t.wait();} // stop for values <= 0 (for manual control)
          else Thread.sleep((int)(60000*preferences.pingInterval));
        } catch (InterruptedException e) {}
        try {preferences.pingInterval = Float.parseFloat(interval.getText());} catch (Exception e) {} // try to parse ping interval
        check.setVisible(false);
        progress.setVisible(true);
        canvas.resetStats();
        for (NetItem item : canvas.items) {
          if (item.getImageID() != 6) {
            // ping mode:
            if (item.getPort() == 70000) { // 70000 = ping, so that way old .netmap won't fail to load
              try { // try to connect and set appropriate color
                if (InetAddress.getByName(item.getIP()).isReachable(preferences.pingTimeout)) {
                  if (!item.getColor().equals(Color.green)) triggers.green(item);
                  canvas.setStatus(item, 1);
                } else {
                  if (!item.getColor().equals(Color.red)) triggers.red(item);
                  canvas.setStatus(item, 3);
                }
              } catch (IOException e) {
                if (!item.getColor().equals(Color.orange)) triggers.orange(item);
                canvas.setStatus(item, 2);
              }
            // port mode:
            } else {
              try { // try to connect and set appropriate color
                progress.setToolTipText("checking: "+item.getIP()+":"+item.getPort());
                Socket sock = new Socket(item.getIP(), item.getPort());
                sock.close();
                if (!item.getColor().equals(Color.green)) triggers.green(item);
                canvas.setStatus(item, 1);
              } catch (UnknownHostException e) {
                if (!item.getColor().equals(Color.orange)) triggers.orange(item);
                canvas.setStatus(item, 2);
              } catch (IOException e) {
                if (!item.getColor().equals(Color.red)) triggers.red(item);
                canvas.setStatus(item, 3);
              }
            }
            progress.setValue(progress.getValue() + (100/canvas.items.size()));
          }
        }
        // clean up
        canvas.updateSwitches();
        progress.setVisible(false);
        check.setVisible(true);
        progress.setValue(0);
        progress.setToolTipText(null);
        preferences.ignoreTriggers = false;
        trayIcon.setToolTip("jNetMap - "+canvas.stats[1]+" up, "+canvas.stats[3]+" down");
      } catch (Exception e) {}
    }
  }

  private void showAbout() {
    JOptionPane.showMessageDialog(f,
        "jNetMap version "+version+"\n\n" +
        "Created by rakudave <public@rakudave.ch>\n" +
        "For more Information, visit www.rakudave.ch/jnetmap\n\n" +
        "This program is free software; you can redistribute it and/or modify\n" +
        "it under the terms of the GNU General Public License as published by\n" +
        "the Free Software Foundation; either version 3 of the License, or\n" +
        "(at your option) any later version.\n\n" +
        "This program is distributed in the hope that it will be useful,\n" +
        "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
        "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" +
        "GNU General Public License for more details.",
        "About", JOptionPane.INFORMATION_MESSAGE);
  }

  private void showBugs() {
    JOptionPane.showMessageDialog(f,
        "Please write to \"bugs@rakudave.ch\" with \"jNetMap\" in the subject line.\n" +
        "Also check for \"Known Issues\" on www.rakudave.ch/jnetmap#issues first.\n\n"+
        "Thanks!",
        "Report a Bug", JOptionPane.INFORMATION_MESSAGE);
  }

  /**
   * Try to open a URL in the default browser.
   * If this fails, show a message with the URL.
   *
   * @param URL to open in the default browser
   */
  public void openURL(String URL) {
    if (Desktop.isDesktopSupported()) {
      Desktop desktop = Desktop.getDesktop();
      if (desktop.isSupported(Desktop.Action.BROWSE)) {
        try {
          desktop.browse(new URI(URL));
        } catch(Exception e) {
          JOptionPane.showMessageDialog(f,
            "Failed to launch your browser!\nLaunch your browser and enter \""+
            URL+"\" into the navigation bar.",
            "Error", JOptionPane.ERROR_MESSAGE);
        }
      }
    } 
  }

  /**
   * Save items and lines to a file using an object stream
   *
   * @param path to the file. If this is <i>null</i>, show selection dialog
   */
  public void saveFile(String path) {
    if (path == null) {// display standard save dialog
      JFileChooser chooser = new JFileChooser();
      FileNameExtensionFilter filter = new FileNameExtensionFilter("jNetMap File (*.netmap)","netmap");
      chooser.setFileFilter(filter);
      int returnValue = chooser.showSaveDialog(f);
      if (returnValue != JFileChooser.APPROVE_OPTION) return; // canceled
      path = chooser.getSelectedFile().toString();
          if (!path.matches("(.*).netmap")) path += ".netmap"; // add ending if not provided
    } else if (password != null) { // ask for password if one exists
      if (!Password.dialog(this, false)) return; // return if canceled (don't save)
    }
        File selectedFile = new File(path);
        for (BackgroundImage img : canvas.backgroundImages) img.removeImage();
        FileOutputStream out = null;
        ObjectOutputStream obj = null;
      try { // try to write two vectors to the file (items and lines)
      out = new FileOutputStream(selectedFile);
      obj = new ObjectOutputStream(out);
      obj.writeObject(canvas.items);
      obj.writeObject(canvas.lines);
      obj.writeObject(password);
      obj.writeObject(canvas.backgroundImages);
      obj.writeObject(canvas.notes);
      obj.close();
      out.close();
      currentFile = path;
      canvas.updateHistory();
      updateRecentDocuments(path);
      f.setTitle("jNetMap - "+selectedFile);
    } catch (Exception e) {
      JOptionPane.showMessageDialog(f, "Failed to write "+selectedFile.getAbsolutePath(), "Error", JOptionPane.ERROR_MESSAGE);
    }
        canvas.repaint();
        canvas.documentChanged = false;
  }

  /**
   * Load items and lines from a file using an object stream
   *
   * @param path to read from. If this is <i>null</i>, show selection dialog
   */
  @SuppressWarnings("unchecked")
  public void openFile(String path) {
    if (canvas.documentChanged) { // only prompt if something has changed
      int option = JOptionPane.showConfirmDialog(f, "Do you wish to save the current map?", "Quit", JOptionPane.YES_NO_CANCEL_OPTION);
      switch (option) {
        case 0: // yes selected
          saveFile(currentFile);
          break;
        case 2: // cancel selected
          return;
        default: // no/close selected
          break;
      }
    }
    File inFile = null;
    if (path == null) { // check if a path was provided as an argument. If not, display a selection dialog
      JFileChooser chooser = new JFileChooser();
      FileNameExtensionFilter filter = new FileNameExtensionFilter("NetMap File (*.netmap)","netmap");
      chooser.setFileFilter(filter);
      if (chooser.showOpenDialog(f) != JFileChooser.APPROVE_OPTION) return;
      path = chooser.getSelectedFile().getAbsolutePath();
      inFile = chooser.getSelectedFile();
    } else {
      inFile = new File(path);
    }
    password = null;
    FileInputStream in = null;
    ObjectInputStream obj = null;
        try { // try to read two vectors from the file
      in = new FileInputStream(inFile);
      obj = new ObjectInputStream(in);
      canvas.items = (Vector<NetItem>) obj.readObject();
      canvas.lines = ensureCompatibility((Vector<NetLine>) obj.readObject());
      try {password = (String) obj.readObject();} catch (Exception e) {}
      try {canvas.backgroundImages = (Vector<BackgroundImage>) obj.readObject();} catch (Exception e) {}
      try {canvas.notes = (Vector<NetNote>) obj.readObject();} catch (Exception e) {}
      in.close();
      obj.close();
      currentFile = path;
      updateRecentDocuments(path);
      for (BackgroundImage img : canvas.backgroundImages) img.reloadImage();
      f.setTitle("jNetMap - "+path);
      canvas.historyPosition = -1;
      canvas.repaint();
      canvas.updateHistory();
      canvas.documentChanged = false;
    } catch (Exception e) {
      JOptionPane.showMessageDialog(f, "Failed to read "+path,"Error", JOptionPane.ERROR_MESSAGE);
    }
  }

  // creates new file (prompt to save current), wipes the canvas
  private void newFile() {
    if (canvas.documentChanged) { // only prompt if something has changed
      int option = JOptionPane.showConfirmDialog(f, "Do you wish to save this map?", "New File", JOptionPane.YES_NO_CANCEL_OPTION);
      switch (option) {
        case 0: // yes selected
          saveFile(currentFile);
          break;
        case 2: // cancel selected
          return;
        default: // no/close selected
          break;
      }
    }
    canvas.clear();
    currentFile = null;
    password = null;
    canvas.documentChanged = false;
    f.setTitle("jNetMap");
  }

  // ensures that all NetLines are of type NetLine2
  private Vector<NetLine2> ensureCompatibility(Vector<NetLine> lines) {
    Vector<NetLine2> newLines = new Vector<NetLine2>(lines.size());
    for (NetLine line : lines) newLines.add(new NetLine2(line));
    return newLines;
  }
 
  private void newPassword() {
    Password.dialog(this, true);
  }
 
  // prompt to save on exit
  private void destroy() {
    if (preferences.askToSave && canvas.documentChanged) { // only prompt if something has changed
      int option = JOptionPane.showConfirmDialog(f, "Do you wish to save the current map?", "Quit", JOptionPane.YES_NO_CANCEL_OPTION);
      switch (option) {
        case 0: // yes selected
          saveFile(currentFile);
          preferences.save();
          System.exit(0);
          break;
        case 2: // cancel selected
          return;
        default: // no/close selected
          preferences.save();
          System.exit(0);
          break;
      }
    } else {
      preferences.save();
      System.exit(0);
    }
  }

  // export the current canvas as a .png file
  private void imageExport() {
    boolean grid = preferences.drawGrid;
    if (grid) preferences.drawGrid = false;
    int width = 0, height = 0;
    canvas.resetCanvas();
    for (NetItem item : canvas.items) {
      if (item.getPosition().x > width) width = item.getPosition().x;
      if (item.getPosition().y > height) height = item.getPosition().y;
    }
    canvas.img = new BufferedImage(width+100, height+100, BufferedImage.TYPE_INT_RGB);
    canvas.g2 = canvas.img.createGraphics();
    canvas.exportPaint = true;
    canvas.repaint();
    JFileChooser chooser = new JFileChooser(); // display standard save dialog
    FileNameExtensionFilter filter = new FileNameExtensionFilter("PNG File","png");
    chooser.setFileFilter(filter);
    int returnValue = chooser.showSaveDialog(f);
    if (returnValue != JFileChooser.APPROVE_OPTION) {canvas.exportPaint = false; canvas.repaint(); return;}; // canceled
    String path = chooser.getSelectedFile().toString();
         if (!path.matches("(.*).png")) path += ".png"; // add ending if not provided
        File selectedFile = new File(path);
        try {
          ImageIO.write(canvas.img, "png", selectedFile);
        } catch (Exception e) {
          JOptionPane.showMessageDialog(f, "Failed to write "+selectedFile.getAbsolutePath(), "Error", JOptionPane.ERROR_MESSAGE);
        }
        if (grid) preferences.drawGrid = true;
    canvas.exportPaint = false;
        canvas.repaint();
  }
 
  // remember 5 recent files, enter them into File > "Recent Files"
  private void updateRecentDocuments(String path) {
    if (path != null) {
      if (!recentFiles.contains(path)) recentFiles.add(0,path);
      if (recentFiles.size() > 5) recentFiles.remove(5);
    }
    recent.removeAll();
    if (!preferences.history) return;
    for (int i = 0; i < recentFiles.size(); i++) {
      final String document = recentFiles.get(i);
      JMenuItem item = new JMenuItem(document);
        item.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {openFile(document);}});
      recent.add(item);
    }
    if (recentFiles.size() > 0) {
      JMenuItem clear = new JMenuItem("Clear History");
        clear.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {recent.removeAll(); recentFiles.clear();}});
      recent.add(new JSeparator());
      recent.add(clear);
    }
  }

  // what to do on startup (open file from argument, scan or display example)
  private void onLaunch(String[] args) {
    if (args.length == 1) { // check if we have to load a file passed as an argument
      openFile(args[0]);
    } else if (preferences.openLast && currentFile != null) {
      openFile(currentFile);
    } else if (preferences.askToScan) { // else load an example
      int option = JOptionPane.showConfirmDialog(f, "Welcome to jNetMap!\nShould I scan your network?", "Welcome", JOptionPane.YES_NO_OPTION);
      switch (option) {
        case 0: // yes selected
          new NetScan(canvas);
          break;
        default: // no selected
          NetItem n1 = new NetItem(0,"127.0.0.1",70000,"example 1",new Point(251,301));
          NetItem n2 = new NetItem(0,"localhost",70000,"example 2",new Point(451,301));
          NetItem n3 = new NetItem(6,"",0,"",new Point(351,201));
          canvas.items.add(n1);
          canvas.items.add(n2);
          canvas.items.add(n3);
          canvas.lines.add(new NetLine2(n1,n3));
          canvas.lines.add(new NetLine2(n2,n3));
          canvas.stats[0] = 2; canvas.stats[4] = 2;
          break;
      }
    }
  }
 
  private void addTrayIcon() {
    if (preferences.trayIcon && SystemTray.isSupported()) {
      PopupMenu popup = new PopupMenu();
        MenuItem hide = new MenuItem("Show/Hide");
          hide.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {if (f.isVisible()) f.setVisible(false); else f.setVisible(true);}});
        MenuItem check = new MenuItem("Check Now");
          check.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {t.interrupt();}});
        MenuItem pref = new MenuItem("Preferences");
          pref.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {preferences.showDialog();}});
        MenuItem doc = new MenuItem("Documentation");
          doc.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {openURL("http://www.rakudave.ch/jnetmap#download");}});
        MenuItem exit = new MenuItem("Exit");
          exit.addActionListener(new ActionListener() {@Override public void actionPerformed(ActionEvent e) {destroy();}});
      popup.add(hide);
      popup.addSeparator();
      popup.add(check);
      popup.add(pref);
      popup.add(doc);
      popup.addSeparator();
      popup.add(exit);
     
      trayIcon = new TrayIcon(Icon.OTHER.getImage(),"jNetMap", popup);
      trayIcon.setImageAutoSize(true);
      trayIcon.addMouseListener(new MouseListener() {
        @Override public void mouseClicked(MouseEvent e) {if (f.isVisible()) f.setVisible(false); else f.setVisible(true);}
        @Override public void mouseEntered(MouseEvent e) {}
        @Override public void mouseExited(MouseEvent e) {}
        @Override public void mousePressed(MouseEvent e) {}
        @Override public void mouseReleased(MouseEvent e) {}
      });
      try {
        SystemTray.getSystemTray().add(trayIcon);
      } catch (AWTException e) {}
    }
  }
}
TOP

Related Classes of ch.rakudave.NetMap.NetMap

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.