package edu.colostate.vchill.gui; import edu.colostate.vchill.ChillDefines.Mode; import edu.colostate.vchill.Config; import edu.colostate.vchill.ScaleManager; import edu.colostate.vchill.ViewControl; import edu.colostate.vchill.chill.ChillMomentFieldScale; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.Observable; import java.util.Observer; /** * The ViewRemotePanel is the panel for the "Basic" tab on the bottom * left of the program. It is a panel of actions that the user is likely * to do browsing actions with. It also contains the actions for setting * the ray step, and finally for selecting a mode to do these actions in. * <p/> * Also contained are the interval setting text fields, the max range and * grid interval setting fields. Finally the ability to set if popup * window actions will affect all the windows, or just the one being * altered. * * @author Justin Carlson * @author Jochen Deyke * @author jpont * @version 2010-08-30 * @created June 1, 2003 */ public class ViewRemotePanel extends JPanel { /** * */ private static final long serialVersionUID = -4935730876904901145L; private final static ViewRemotePanel vrp = new ViewRemotePanel(); private final ViewActions actions = new ViewActions(); private final Config config = Config.getInstance(); private final ViewControl vc = ViewControl.getInstance(); private final ScaleManager sm = ScaleManager.getInstance(); private final WindowManager wm = WindowManager.getInstance(); private final JTextField rayField = new JTextField(String.valueOf(config.getRayStep()), 2); private final JTextField minField = new JTextField(5); private final JTextField maxField = new JTextField(5); private final JTextField gridIntervalField = new JTextField(String.valueOf(config.getGridSpacing()), 5); private final JTextField plotRange = new JTextField(String.format("%.3g", config.getPlotRange()), 5); private final JTextField RHIvField = new JTextField(String.format("%.3g", config.getRHIHVFactor()), 5); private final JTextField RHIhField = new JTextField(String.format("%.3g", config.getMaxPlotHeight()), 5); private final JComboBox typesBox = new JComboBox(sm.getTypes().toArray()); /** * This basic constructor will call the helper methods and setup the * size and layout of the inner components. Private default constructor * prevents instantiation. */ private ViewRemotePanel() { typesBox.setAction(new AbstractAction() { /** * */ private static final long serialVersionUID = -6270176955419819841L; public void actionPerformed(final ActionEvent ae) { ChillMomentFieldScale scale = sm.getScale((String) typesBox.getSelectedItem()); if (scale == null) return; minField.setText(String.format("%.3g", scale.getMin())); maxField.setText(String.format("%.3g", scale.getMax())); } }); if (sm.getTypes().size() > 0) { typesBox.setSelectedIndex(0); } setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); add(createSweepButtons()); add(createRayButtons()); add(createModeSelectionBoxes()); add(createIntervalInput()); add(createRHIOptions()); add(createOptionPanel()); add(createGlobalOptions()); add(createBookmarkOptions()); sm.addObserver(new Observer() { public void update(final Observable o, final Object arg) { typesBox.removeAllItems(); for (String type : sm.getTypes()) typesBox.addItem(type); } }); } public static ViewRemotePanel getInstance() { return vrp; } /** * Creates buttons for the actions first, previous, next and last. * * @return the panel containing the four buttons */ private JPanel createSweepButtons() { JPanel inputPanel = new JPanel(); inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS)); JButton button; button = new JButton(actions.doFirstAction); button.setToolTipText("Go to the first sweep in this volume"); inputPanel.add(button); button = new JButton(actions.doPrevAction); button.setToolTipText("Go to the previous sweep in this volume"); inputPanel.add(button); button = new JButton(actions.doNextAction); button.setToolTipText("Go to the next sweep in this volume"); inputPanel.add(button); button = new JButton(actions.doLastAction); button.setToolTipText("Go to the last sweep in this volume"); inputPanel.add(button); return inputPanel; } /** * Creates the stop action, the input for ray steps, and the the labels * to go along with the input box. * * @return A Panel with Text fields for setting ray information. */ private JPanel createRayButtons() { JPanel inputPanel = new JPanel(); inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS)); JButton button; button = new JButton(actions.doFirstRayAction); button.setToolTipText("Go to the first ray in this sweep"); inputPanel.add(button); button = new JButton(actions.doPrevRayAction); button.setToolTipText("Go to the previous ray in this sweep"); inputPanel.add(button); JLabel information = new JLabel(" Step: "); inputPanel.add(information); MyAction action = new MyAction() { protected void update() { String rayText = rayField.getText(); if (Double.parseDouble(rayText) < 1.0) { /* the interval must be at least 1 */ rayField.setText("1"); } config.setRayStep(rayField.getText()); } }; rayField.addActionListener(action); rayField.addFocusListener(action); rayField.setToolTipText("Step size for the next and previous ray operations"); inputPanel.add(rayField); button = new JButton(actions.doNextRayAction); button.setToolTipText("Go to the next ray in this sweep"); inputPanel.add(button); button = new JButton(actions.doLastRayAction); button.setToolTipText("Go to the last ray in this sweep"); inputPanel.add(button); return inputPanel; } private JPanel createRHIOptions() { JPanel inputPanel = new JPanel(); inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS)); MyAction action; inputPanel.add(new JLabel("RHI Vstretch:")); action = new MyAction() { protected void update() { String RHIvText = RHIvField.getText(); if (RHIvText.indexOf("-") != -1) { /* don't allow negative numbers */ RHIvField.setText("0.0"); } config.setRHIHVFactor(RHIvField.getText()); wm.replotOverlay(); } }; RHIvField.addActionListener(action); RHIvField.addFocusListener(action); RHIvField.setToolTipText("Vertical to horizontal stretch ratio"); inputPanel.add(RHIvField); inputPanel.add(new JLabel(" RHI height:")); action = new MyAction() { protected void update() { String RHIhText = RHIhField.getText(); if (RHIhText.indexOf("-") != -1) { /* don't allow negative numbers */ RHIhField.setText("0.0"); } config.setMaxPlotHeight(RHIhField.getText()); wm.replotOverlay(); } }; RHIhField.addActionListener(action); RHIhField.addFocusListener(action); RHIhField.setToolTipText("Limit RHI height to this distance (km)"); inputPanel.add(RHIhField); return inputPanel; } /** * Creates a panel containing the Interval setting fields and the * pulldown menu for selecting what data type is affected. * * @return A Panel with Interval setting options. */ private JPanel createIntervalInput() { JPanel inputPanel = new JPanel(); inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS)); MyAction action = new MyAction() { protected void update() { setPlotInterval((String) typesBox.getSelectedItem(), maxField.getText(), minField.getText()); } }; typesBox.setToolTipText("Adjust color scale for this data type"); inputPanel.add(typesBox); inputPanel.add(new JLabel(" Min:")); minField.addActionListener(action); minField.addFocusListener(action); minField.setToolTipText("Minimum data value for color scale"); inputPanel.add(minField); inputPanel.add(new JLabel(" Max:")); maxField.addActionListener(action); maxField.addFocusListener(action); maxField.setToolTipText("Maximum data value for color scale"); inputPanel.add(maxField); return inputPanel; } /** * A Panel for setting the grid interval (how often the * lines are drawn in km) and the max plot range (how far * out to draw the lines and data). * * @return The freshly created option panel */ private JPanel createOptionPanel() { JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); MyAction action; panel.add(new JLabel("Spacing (km):")); action = new MyAction() { protected void update() { String gridIntervalText = gridIntervalField.getText(); if (Double.parseDouble(gridIntervalText) < 1.0) { /* the interval must be at least 1 */ gridIntervalField.setText("1"); } config.setGridSpacing(gridIntervalField.getText()); wm.replotOverlay(); } }; gridIntervalField.addActionListener(action); gridIntervalField.addFocusListener(action); gridIntervalField.setToolTipText("Draw range rings/grid every this many km"); panel.add(gridIntervalField); panel.add(new JLabel(" Range (km):")); action = new MyAction() { protected void update() { String plotRangeText = plotRange.getText(); if (Double.parseDouble(plotRangeText) <= 0.0) { /* the range must be at least 1 */ plotRange.setText("1"); } config.setPlotRange(plotRange.getText()); wm.replotOverlay(); } }; plotRange.addActionListener(action); plotRange.addFocusListener(action); plotRange.setToolTipText("Limit plot range to this distance (km)"); panel.add(plotRange); return panel; } /** * This will set all the currently open windows of a given type to * hash their data according to these new max and min values. * * @param type The Type of data to set these new values into. * @param max The maximum value to be used for the data hashing. * @param min The minimum value to be used for the data hashing. */ private void setPlotInterval(final String type, final String max, final String min) { if (type == null || max == null || min == null) return; if (max.length() < 1 || min.length() < 1) return; vc.setPlotInterval(type, max, min); } /** * This is just a simple private method to allow for the creation of * radio buttons that will be encapsulated in a JPanel. These * buttons will effect which plotting method is used, by ray, by sweep * or by volume. * * @return A JPanel with a set of Radio buttons */ private JPanel createModeSelectionBoxes() { JPanel modePanel = new JPanel(); modePanel.setLayout(new BoxLayout(modePanel, BoxLayout.X_AXIS)); modePanel.add(new JLabel("Mode: ")); ButtonGroup group = new ButtonGroup(); for (final Mode mode : Mode.values()) { JRadioButton button = new JRadioButton(mode.toString() + " "); button.setToolTipText(mode.DESCRIPTION); if (mode == config.getPlottingMode()) button.setSelected(true); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { config.setPlottingMode(mode); } }); group.add(button); modePanel.add(button); } return modePanel; } /** * This method will create a panel with the apply button and * affect all options box. * * @return The new options panel */ private JPanel createGlobalOptions() { JPanel inputPanel = new JPanel(); inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.X_AXIS)); JButton button = new JButton(actions.doStopAction); button.setToolTipText("Click to stop this plot"); inputPanel.add(button); inputPanel.add(new JButton(new AbstractAction("Apply / Replot") { /** * */ private static final long serialVersionUID = -9061249180042696285L; public void actionPerformed(ActionEvent ae) { config.setPlotRange(plotRange.getText()); config.setGridSpacing(gridIntervalField.getText()); setPlotInterval((String) typesBox.getSelectedItem(), maxField.getText(), minField.getText()); config.setRayStep(rayField.getText()); config.setRHIHVFactor(RHIvField.getText()); config.setMaxPlotHeight(RHIhField.getText()); wm.replotOverlay(); vc.rePlot(); } })); return inputPanel; } private JPanel createBookmarkOptions() { JPanel BookmarkPanel = new JPanel(); BookmarkPanel.setLayout(new BoxLayout(BookmarkPanel, BoxLayout.X_AXIS)); BookmarkPanel.add(new JButton(new AbstractAction("Create Bookmark") { /** * */ private static final long serialVersionUID = 4134687274631014923L; public void actionPerformed(ActionEvent ae) { vc.createBookmark(); } })); return BookmarkPanel; } /** * Reloads text fields based on current settings in Config */ public void update() { plotRange.setText(String.format("%.3g", config.getPlotRange())); RHIhField.setText(String.format("%.3g", config.getMaxPlotHeight())); gridIntervalField.setText(String.valueOf(config.getGridSpacing())); typesBox.setSelectedItem(typesBox.getSelectedItem()); } public void setSelection(final String type) { typesBox.setSelectedItem(type); } private abstract class MyAction implements ActionListener, FocusListener { public void actionPerformed(final ActionEvent ae) { update(); vc.rePlot(); } public void focusLost(final FocusEvent fe) { update(); } public void focusGained(final FocusEvent fe) { } //do nothing protected abstract void update(); } }