package edu.colostate.vchill.plot; import edu.colostate.vchill.*; import edu.colostate.vchill.Config.GradientType; import edu.colostate.vchill.gui.ViewFilterPanel; import edu.colostate.vchill.gui.ViewRemotePanel; import edu.colostate.vchill.gui.ViewWindowActions; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.io.IOException; import java.util.Enumeration; import java.util.Observable; import java.util.Observer; /** * This class is used to create a popup window. The user creates the class and * then calls "getPopup()" To actually have access to it. * * @author Justin Carlson * @author Jochen Deyke * @version 2007-09-26 * @created January 04, 2003 */ class ViewPlotPopup extends ViewWindowActions { private static final ViewControl vc = ViewControl.getInstance(); private static final Config config = Config.getInstance(); private static final ScaleManager sm = ScaleManager.getInstance(); private static final ViewRemotePanel vrp = ViewRemotePanel.getInstance(); private static final ViewFilterPanel vfp = ViewFilterPanel.getInstance(); private JPopupMenu popup; private JMenu typeMenu; private JMenu thresholdMenu; private JCheckBoxMenuItem checkBoxGrid; private JCheckBoxMenuItem checkBoxMap; private JCheckBoxMenuItem checkBoxAircraft; private JCheckBoxMenuItem checkBoxClickPoint; private JCheckBoxMenuItem checkBoxSmoothing; private JCheckBoxMenuItem checkBoxNoise; private JCheckBoxMenuItem checkBoxThreshold; private ButtonGroup modeGroup; private JRadioButtonMenuItem unfoldingOff; private JRadioButtonMenuItem unfoldingAutomatic; private JRadioButtonMenuItem unfoldingManual; private JRadioButtonMenuItem gradientOff; private JRadioButtonMenuItem gradientRange; private JRadioButtonMenuItem gradientAzimuth; private JMenuItem export; private volatile int x, y; protected final ViewPlotWindow win; /** * This creates the basic items, and then calls methods to actually * initialize all the different items we want to create. * * @param win The window this menu will be shown in */ public ViewPlotPopup(final ViewPlotWindow win) { super(win); this.win = win; //Init the main popup. this.popup = new JPopupMenu(); this.popup.add(new AbstractAction("Center here") { /** * */ private static final long serialVersionUID = -5183097622394096461L; public void actionPerformed(final ActionEvent ae) { recenter(x, y); } }); this.popup.add(new AbstractAction("Reset center") { /** * */ private static final long serialVersionUID = -717097542811205583L; public void actionPerformed(final ActionEvent ae) { config.setCenterX(0); config.setCenterY(0); wm.setCenterInKm(); wm.clearScreen(); vc.rePlot(); } }); //Add a seperator on the popup menu, pure apperance. this.popup.addSeparator(); makeZoomSubmenu(); makeOverlaySubmenu(); makePlotFiltersSubmenu(); makeWindowTypeSubmenu(); //makeThresholdTypeSubmenu(); makePlotTypeSubmenu(); //Add a seperator on the popup menu, pure apperance. this.popup.addSeparator(); //Make the items that will not go into a submenu, these //are actions such as set PPI Range etc. makeMenuItems(); sm.addObserver(new Observer() { public void update(final Observable o, final Object arg) { updateTypeMenu(); //updateThresholdMenu(); } }); } public void recenter(final int x, final int y) { win.recenter(x, y); wm.clearScreen(); vc.rePlot(); } /** * Makes the options dealing with zooming. */ private void makeZoomSubmenu() { JMenu subMenu = new JMenu("Zoom"); subMenu.add(new AbstractAction("Reset zoom & center") { /** * */ private static final long serialVersionUID = -9204285339455351504L; public void actionPerformed(final ActionEvent ae) { config.setPlotRange(config.getMaxPlotRange()); ViewRemotePanel.getInstance().update(); config.setCenterX(0); config.setCenterY(0); wm.setCenterInKm(); wm.replotOverlay(); wm.clearScreen(); System.out.println("Reset zoom & center"); vc.rePlot(); } }).setIcon(null); final int maxZoom = 7; for (int z = 0; z < maxZoom; ++z) { final double zoom = Math.pow(2, z); final String label = zoom + "x Zoom"; subMenu.add(new AbstractAction(label) { /** * */ private static final long serialVersionUID = 2814400692900567120L; public void actionPerformed(final ActionEvent ae) { config.setPlotRange(config.getMaxPlotRange() / zoom); ViewRemotePanel.getInstance().update(); wm.setCenterInKm(); wm.replotOverlay(); wm.clearScreen(); System.out.println(label); vc.rePlot(); } }).setIcon(null); } this.popup.add(subMenu); } /** * Creates the two checkbox items that are used to turn on and off the * map underlays and ring overlays. */ //NOTE: array indeces depend on order in ViewPlotActions.java private void makeOverlaySubmenu() { JMenu subMenu = new JMenu("Overlays"); checkBoxGrid = new JCheckBoxMenuItem(new AbstractAction("Draw Grids") { /** * */ private static final long serialVersionUID = 5246928330014976639L; public void actionPerformed(final ActionEvent ae) { System.out.println("Grid on/off"); config.toggleGridEnabled(); wm.replotOverlay(); wm.repaintPlotWindows(); } }); subMenu.add(checkBoxGrid); checkBoxMap = new JCheckBoxMenuItem(new AbstractAction("Draw Map") { /** * */ private static final long serialVersionUID = -3309823688651178046L; public void actionPerformed(final ActionEvent ae) { System.out.println("Map on/off"); config.toggleMapEnabled(); wm.replotOverlay(); wm.repaintPlotWindows(); } }); subMenu.add(checkBoxMap); //functionality now in main menu checkBoxAircraft = new JCheckBoxMenuItem(new AbstractAction("Draw Aircraft") { /** * */ private static final long serialVersionUID = -3657977659018453626L; public void actionPerformed(final ActionEvent ae) { System.out.println("Aircraft on/off"); config.toggleAircraftEnabled(); //vc.rePlot(); wm.repaintPlotWindows(); } }); subMenu.add(checkBoxAircraft); checkBoxClickPoint = new JCheckBoxMenuItem(new AbstractAction("Draw Click Point") { /** * */ private static final long serialVersionUID = 8662695079265497420L; public void actionPerformed(final ActionEvent ae) { System.out.println("Click Point on/off"); config.toggleClickPointEnabled(); wm.repaintPlotWindows(); } }); subMenu.add(checkBoxClickPoint); this.popup.add(subMenu); } //NOTE: array indeces depend on order in ViewPlotActions.java private void makePlotFiltersSubmenu() { JMenu subMenu = new JMenu("Filters"); ButtonGroup unfoldingGroup = new ButtonGroup(); ButtonGroup gradientGroup = new ButtonGroup(); checkBoxThreshold = new JCheckBoxMenuItem(new AbstractAction("Threshold Filter") { /** * */ private static final long serialVersionUID = -6885821132504243726L; public void actionPerformed(final ActionEvent ae) { System.out.println("Threshold Toggle"); config.toggleThresholdEnabled(); ViewRemotePanel.getInstance().update(); vfp.update(); wm.calculateOpenWindows(); vc.rePlot(); } }); subMenu.add(checkBoxThreshold); checkBoxSmoothing = new JCheckBoxMenuItem(new AbstractAction("Smoothing") { /** * */ private static final long serialVersionUID = 1724345064471645327L; public void actionPerformed(final ActionEvent ae) { System.out.println("Smooth Toggle"); config.toggleSmoothingEnabled(); vfp.update(); vc.rePlot(); } }); subMenu.add(checkBoxSmoothing); checkBoxNoise = new JCheckBoxMenuItem(new AbstractAction("Noise Filter") { /** * */ private static final long serialVersionUID = 8480083012610236006L; public void actionPerformed(final ActionEvent ae) { System.out.println("Noise Toggle"); config.toggleNoiseReductionEnabled(); vfp.update(); vc.rePlot(); } }); subMenu.add(checkBoxNoise); JMenu subSubMenu = new JMenu("Velocity Unfolding"); unfoldingOff = new JRadioButtonMenuItem(new AbstractAction("No Unfolding") { /** * */ private static final long serialVersionUID = 8844143140897533112L; public void actionPerformed(final ActionEvent ae) { System.out.println("Disable Velocity Unfolding"); config.setUnfoldingEnabled(false); vfp.update(); vc.rePlot(); } }); unfoldingOff.setIcon(null); unfoldingGroup.add(unfoldingOff); subSubMenu.add(unfoldingOff); unfoldingAutomatic = new JRadioButtonMenuItem(new AbstractAction("Automatic Unfolding") { /** * */ private static final long serialVersionUID = 581835316212375036L; public void actionPerformed(final ActionEvent ae) { System.out.println("Automatic Velocity Unfolding"); config.setUnfoldingEnabled(true); config.setUnfoldingAutomatic(true); vfp.update(); vc.rePlot(); } }); unfoldingAutomatic.setIcon(null); unfoldingGroup.add(unfoldingAutomatic); subSubMenu.add(unfoldingAutomatic); unfoldingManual = new JRadioButtonMenuItem(new AbstractAction("Manual Unfolding") { /** * */ private static final long serialVersionUID = 4080994908740585452L; public void actionPerformed(final ActionEvent ae) { System.out.println("Manual Velocity Unfolding"); config.setUnfoldingEnabled(true); config.setUnfoldingAutomatic(false); vfp.update(); vc.rePlot(); } }); unfoldingManual.setIcon(null); unfoldingGroup.add(unfoldingManual); subSubMenu.add(unfoldingManual); JMenuItem inputEstimates = new JMenuItem(new AbstractAction("Input New Velocity Estimates") { /** * */ private static final long serialVersionUID = 8614615170709872271L; public void actionPerformed(final ActionEvent ae) { System.out.println("Input Manual Unfolding Estimates"); String result = DialogUtil.showMultilineInputDialog("Input", "Please enter estimated velocities, one per line.\nFormat is <height in km><space><estimated velocity in m/s>\nEntered values remain in effect until the program is shut down or new numbers are entered.\nOrdering of heights is not important. Faulty lines are ignored.", EstimateParser.getInstance().toString()); if (result == null) return; //canceled; EstimateParser.getInstance().parse(result); config.setUnfoldingEnabled(true); config.setUnfoldingAutomatic(false); vfp.update(); vc.rePlot(); } }); subSubMenu.add(inputEstimates); subMenu.add(subSubMenu); subSubMenu = new JMenu("Z as Gradient"); gradientOff = new JRadioButtonMenuItem(new AbstractAction("Gradient Off") { /** * */ private static final long serialVersionUID = 7890235569742795608L; public void actionPerformed(final ActionEvent ae) { System.out.println("Gradient Off"); config.setGradientType(GradientType.Off); vfp.update(); vc.rePlot(); } }); gradientOff.setIcon(null); gradientGroup.add(gradientOff); subSubMenu.add(gradientOff); gradientRange = new JRadioButtonMenuItem(new AbstractAction("Range Gradient") { /** * */ private static final long serialVersionUID = 8977826728579431789L; public void actionPerformed(final ActionEvent ae) { System.out.println("Z Range Gradient"); config.setGradientType(GradientType.Range); vfp.update(); vc.rePlot(); } }); gradientRange.setIcon(null); gradientGroup.add(gradientRange); subSubMenu.add(gradientRange); gradientAzimuth = new JRadioButtonMenuItem(new AbstractAction("Azimuth Gradient") { /** * */ private static final long serialVersionUID = 6159375085307055137L; public void actionPerformed(final ActionEvent ae) { System.out.println("Z Azimuth Gradient"); config.setGradientType(GradientType.Azimuth); vfp.update(); vc.rePlot(); } }); gradientAzimuth.setIcon(null); gradientGroup.add(gradientAzimuth); subSubMenu.add(gradientAzimuth); subMenu.add(subSubMenu); this.popup.add(subMenu); } public void resetInfo() { export.setEnabled(win.isExportable()); checkBoxGrid.setState(config.isGridEnabled()); checkBoxMap.setState(config.isMapEnabled()); checkBoxAircraft.setState(config.isAircraftEnabled()); checkBoxClickPoint.setState(config.isClickPointEnabled()); checkBoxThreshold.setState(config.isThresholdEnabled()); checkBoxSmoothing.setState(config.isSmoothingEnabled()); checkBoxNoise.setState(config.isNoiseReductionEnabled()); if (config.isUnfoldingEnabled()) { if (config.isUnfoldingAutomatic()) unfoldingAutomatic.setSelected(true); else unfoldingManual.setSelected(true); } else unfoldingOff.setSelected(true); switch (config.getGradientType()) { case Range: gradientRange.setSelected(true); break; case Azimuth: gradientAzimuth.setSelected(true); break; default: gradientOff.setSelected(true); break; } Enumeration buttons = modeGroup.getElements(); while (buttons.hasMoreElements()) { JRadioButtonMenuItem tmp = (JRadioButtonMenuItem) buttons.nextElement(); if (win.getPlotMode().equals(tmp.getText())) { tmp.setSelected(true); break; } } } /** * A Submenu for changing the type of data the window is associated * with. For example, if the Z submenu item is called, this window * will now request Z data. */ public void makeWindowTypeSubmenu() { this.typeMenu = new JMenu("Window Type"); this.updateTypeMenu(); this.popup.add(this.typeMenu); } public void updateTypeMenu() { this.typeMenu.removeAll(); ButtonGroup typeGroup = new ButtonGroup(); for (final String type : sm.getTypes()) { JRadioButtonMenuItem button = new JRadioButtonMenuItem(new AbstractAction(type) { /** * */ private static final long serialVersionUID = -8486740924090424419L; public void actionPerformed(final ActionEvent ae) { System.out.println("Type set to: " + type); win.setType(type); win.rePlotDrawingArea(); vc.rePlot(); } }); button.setSelected(win.getType().equals(type)); typeGroup.add(button); this.typeMenu.add(button).setIcon(null); } } public void makeThresholdTypeSubmenu() { this.thresholdMenu = new JMenu("Threshold Type"); this.updateThresholdMenu(); this.popup.add(this.thresholdMenu); } public void updateThresholdMenu() { this.thresholdMenu.removeAll(); ButtonGroup thresholdGroup = new ButtonGroup(); for (final String type : sm.getTypes()) { JRadioButtonMenuItem button = new JRadioButtonMenuItem(new AbstractAction(type) { /** * */ private static final long serialVersionUID = 2585285358552142918L; public void actionPerformed(final ActionEvent ae) { System.out.println("Threshold type set to: " + type); config.setThresholdType(type); wm.calculateOpenWindows(); vc.rePlot(); } }); button.setSelected(type.equals(config.getThresholdType())); thresholdGroup.add(button); this.thresholdMenu.add(button).setIcon(null); } } private void makePlotTypeSubmenu() { JMenu subMenu = new JMenu("Plot as"); modeGroup = new ButtonGroup(); for (Action a : new Action[]{ new AbstractAction("<auto>") { /** * */ private static final long serialVersionUID = 5567409497489739676L; public void actionPerformed(final ActionEvent ae) { wm.setMode("auto"); vc.rePlot(); } }, new AbstractAction("PPI") { /** * */ private static final long serialVersionUID = -1918608598471232900L; public void actionPerformed(final ActionEvent ae) { wm.setMode("PPI"); vc.rePlot(); } }, new AbstractAction("RHI") { /** * */ private static final long serialVersionUID = -3579131172991048635L; public void actionPerformed(final ActionEvent ae) { wm.setMode("RHI"); vc.rePlot(); } }, new AbstractAction("Time/Height") { /** * */ private static final long serialVersionUID = -6676960179887172622L; public void actionPerformed(final ActionEvent ae) { wm.setMode("MAN"); vc.rePlot(); } }, }) { JRadioButtonMenuItem button = new JRadioButtonMenuItem(a); button.setIcon(null); modeGroup.add(button); subMenu.add(button); } this.popup.add(subMenu); } /** * Sets up the Menu Options such as Saving */ private void makeMenuItems() { for (JMenuItem i : makePopupItems()) this.popup.add(i).setIcon(null); final String osname = System.getProperty("os.name"); export = new JMenuItem(new AbstractAction("Launch Google Earth") { /** * */ private static final long serialVersionUID = -8532816222005083257L; public void actionPerformed(final ActionEvent ae) { try { String zipfile = win.export(null); //to tmpfile if (zipfile != null) DialogUtil.open(zipfile); } catch (IOException ioe) { ioe.printStackTrace(); } } }); if (osname.startsWith("Windows") || osname.equals("Mac OS X") || osname.equals("Linux")) this.popup.add(export).setIcon(null); } void show(final MouseEvent e) { resetInfo(); this.popup.show(e.getComponent(), x = e.getX(), y = e.getY()); } void hide() { this.popup.setVisible(false); } }