package genegui; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.io.*; import javax.swing.event.*; import javax.swing.*; import main.*; /** NodeStateViewer.java This viewer displays all the values for all the nodes of a selected cell. The user may also set the values. The cell being displayed may be selected from a cell surface view at the top. @author WJS */ public class NodeStateViewer extends JInternalFrame implements ModelStateChangeListener, GuiInterface { /** The Index of the cell presently being viewed */ private int CellIndex = 0; /** The panel the cell outlines are painted onto */ private CellPaintPanel TheCellPaintPanel; /** Preferred dimension for the CellPaintPanel */ private Dimension CellPaintPanelDimension; /** Stores the base cell shapes and locations */ private Polygon[] CellShapeArray; /** The Main panel that stores all */ private JPanel MainPanel; /** An array with all the NodePanels */ private NodePanel[] NodePanels; /** Self reference */ private JInternalFrame SaveThis = this; /** The scale at which to draw the cell shape objects */ private double Scale = 5.0; /** Timer for killing the popup slider windows in case the user doesn't touch them */ private Timer SliderDeathTimer=null; /** A JWindow for holding a popup slider. It is a class variable so we can make sure we allow only one to be open at a time. */ private JWindow SliderWindow = null; /** The MainGui object that this belongs to */ private MainGui TheMainGui; /** The ModelState that this ModelStateNodePalette is attached to */ private ModelState TheModelState; /** Translation for drawing of cells */ private Point Translation = new Point(5,5); /** Primary constructor. @param ModelState theModelState @author WJS */ public NodeStateViewer(ModelState theModelState, MainGui theMainGUI, String title) { super(title,true,true,true,true); TheModelState = theModelState; TheMainGui = theMainGUI; // Establish the main panel MainPanel = new JPanel(); MainPanel.setLayout(new BoxLayout(MainPanel,BoxLayout.Y_AXIS)); MainPanel.setBackground(Color.lightGray); setContentPane(MainPanel); // Make panel that shows the selected cell // Build the cell shape array CellShapeArray = new Polygon[theModelState.getNumberOfCells()]; Polygon p; Polygon q; for (int i=0;imaxX) maxX = rect.getX()+rect.getWidth(); if ((rect.getY()+rect.getHeight())>maxY) maxY = rect.getY()+rect.getHeight(); } CellPaintPanelDimension = new Dimension((int)maxX+20,(int)maxY+4); TheCellPaintPanel = new CellPaintPanel(); MainPanel.add(TheCellPaintPanel); // Make a panel that holds all the node panels JPanel nodeListPanel = new JPanel(); nodeListPanel.setLayout(new BoxLayout(nodeListPanel,BoxLayout.Y_AXIS)); // Add a NodePanel for each node in the ModelState NodeTemplate[] nodes = TheModelState.getNodeTemplates(); NodePanels = new NodePanel[nodes.length]; for (int i=0;i
  • Icon
  • Name
  • Color swatch
    And the following controls whose values vary depending upon the active ModelStateView.
  • value
  • value/range slider control
    @author WJS */ private class NodePanel extends JPanel { /** The color swatch shows the color of the Node */ private JPanel ColorSwatch; /** A filler panel for pushing things up */ private JPanel Filler; /** JTextField for showing/chaning initial value of */ private JTextField InitialNodeValueJTextField; /** A slider icon used for invoking a slider for easily changing the node initial value */ private JButton InitialValueSliderIcon; /** A JLabel holding the node name and descriptive icon */ private JLabel NodeName; /** The texfield for holding the curret value of the node */ private JTextField NodeValueJTextField; /** The NodeTemplate that this NodePanel is attached to */ private NodeTemplate TheNodeTemplate; /** A slider icon used for invoking a slider for easily changing the node value */ private JButton ValueSliderIcon; /** Constructor builds the visual appearance of the NodePanel and sets up listeners. @param NodeTemplate theNodeTemplate - The NodeTemplate this is attached to. @author WJS */ public NodePanel(NodeTemplate theNodeTemplate) { super(); TheNodeTemplate = theNodeTemplate; setLayout(new BoxLayout(this,BoxLayout.X_AXIS)); setBorder(BorderFactory.createLineBorder(Color.black,1)); setMaximumSize(new Dimension(2048,24)); setBackground(Color.white); // Node icon/name label NodeName = new JLabel(TheNodeTemplate.getName(),TheNodeTemplate.getIcon(),SwingConstants.LEFT); NodeName.setOpaque(true); NodeName.setBackground(Color.lightGray); NodeName.setBorder(BorderFactory.createMatteBorder(2,0,2,0,Color.lightGray)); add(NodeName); // A filler panel Filler = new JPanel(); Filler.setOpaque(true); Filler.setBackground(Color.lightGray); add(Filler); // Percent Sign JLabel ps = new JLabel("init: %"); ps.setBorder(BorderFactory.createMatteBorder(0,4,0,2,getBackground())); add(ps); // InitialNodeValue Text Field // Value TextField InitialNodeValueJTextField = new JTextField(); InitialNodeValueJTextField.setMaximumSize(new Dimension(48,20)); InitialNodeValueJTextField.setMinimumSize(new Dimension(48,20)); InitialNodeValueJTextField.setPreferredSize(new Dimension(48,20)); InitialNodeValueJTextField.setHorizontalAlignment(JTextField.RIGHT); InitialNodeValueJTextField.setText(""); InitialNodeValueJTextField.setDisabledTextColor(Color.black); InitialNodeValueJTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { try { float value = Float.parseFloat(InitialNodeValueJTextField.getText()); TheModelState.getModel().cells[CellIndex].setInitialValue(TheNodeTemplate.getNodeNum(),value/100); } catch (NumberFormatException nfe) { // TODO chuck an error } } }); add(InitialNodeValueJTextField); // Slider invoker InitialValueSliderIcon = new JButton(new ImageIcon("icons/MSESliderIcon.gif")); InitialValueSliderIcon.setDisabledIcon(new ImageIcon("icons/MSESliderIconDisabled.gif")); InitialValueSliderIcon.setBorder(BorderFactory.createMatteBorder(2,4,2,2,getBackground())); InitialValueSliderIcon.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { // Create a window with a slider and position the slider so the handle // matches up with the current mouse location. When user releases // mouse from click, mouse will be right on the handle. // Get the value int value; try { value = (int)Float.parseFloat(InitialNodeValueJTextField.getText()); } catch (Exception ex) { value = 0; } // Get rid of any slider and death that's still around. if (SliderDeathTimer!=null) SliderDeathTimer.stop(); if (SliderWindow!=null) SliderWindow.dispose(); SliderWindow = new JWindow(); final JSlider slider = new JSlider(SwingConstants.VERTICAL,0,100,value); slider.setBorder(BorderFactory.createLineBorder(Color.black,1)); // Set up a change listener to allow slider to change node values. slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ce) { float value = slider.getValue(); InitialNodeValueJTextField.setText(Float.toString(value)); TheModelState.getModel().cells[CellIndex].setInitialValue(TheNodeTemplate.getNodeNum(),value/100); } }); // Set up a mouse listener that will slider.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { // If the SliderDeathTimer is running, kill it. if (SliderDeathTimer!=null) { SliderDeathTimer.stop(); SliderDeathTimer = null; } } public void mouseReleased(MouseEvent me) { // When user releases the mouse close the slider window. SliderWindow.dispose(); SliderWindow=null; } }); // Create a timer that kills of the window in case a niave user // brings it up and does nothing with it. SliderDeathTimer = new Timer(4000,new ActionListener() { public void actionPerformed(ActionEvent ae) { SliderWindow.dispose(); SliderWindow=null; SliderDeathTimer.stop(); SliderDeathTimer=null; } }); SliderDeathTimer.start(); SliderWindow.setContentPane(slider); SliderWindow.pack(); // Position the slider so habdle lines up with the mouse Point p = InitialValueSliderIcon.getLocationOnScreen(); p.x -= slider.getWidth()/2 - me.getX(); p.y -= (1.0-value/100.0)*slider.getHeight()-me.getY(); SliderWindow.setLocation(p); SliderWindow.setVisible(true); } }); add(InitialValueSliderIcon); // Color swatch JPanel colorSwatchBorder = new JPanel(); colorSwatchBorder.setLayout(new BorderLayout()); colorSwatchBorder.setBorder(BorderFactory.createMatteBorder(2,4,2,4,getBackground())); colorSwatchBorder.setMaximumSize(new Dimension(28,24)); colorSwatchBorder.setMinimumSize(new Dimension(28,24)); colorSwatchBorder.setPreferredSize(new Dimension(28,24)); ColorSwatch = new JPanel(); ColorSwatch.setMaximumSize(new Dimension(20,20)); ColorSwatch.setMinimumSize(new Dimension(20,20)); ColorSwatch.setPreferredSize(new Dimension(20,20)); ColorSwatch.setBackground(TheNodeTemplate.getColor()); ColorSwatch.setBorder(BorderFactory.createLineBorder(Color.black,1)); colorSwatchBorder.add(ColorSwatch,BorderLayout.CENTER); add(colorSwatchBorder); // Percent Sign ps = new JLabel("value: %"); ps.setBorder(BorderFactory.createMatteBorder(0,4,0,2,getBackground())); add(ps); // Value TextField NodeValueJTextField = new JTextField(); NodeValueJTextField.setMaximumSize(new Dimension(48,20)); NodeValueJTextField.setMinimumSize(new Dimension(48,20)); NodeValueJTextField.setPreferredSize(new Dimension(48,20)); NodeValueJTextField.setHorizontalAlignment(JTextField.RIGHT); NodeValueJTextField.setText(""); NodeValueJTextField.setDisabledTextColor(Color.black); NodeValueJTextField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { try { float value = Float.parseFloat(NodeValueJTextField.getText()); TheModelState.updateNodeValue(CellIndex,TheNodeTemplate.getNodeNum(),value/100, (ModelStateChangeListener)SaveThis); } catch (NumberFormatException nfe) { // TODO chuck an error } } }); add(NodeValueJTextField); // Slider invoker ValueSliderIcon = new JButton(new ImageIcon("icons/MSESliderIcon.gif")); ValueSliderIcon.setDisabledIcon(new ImageIcon("icons/MSESliderIconDisabled.gif")); ValueSliderIcon.setBorder(BorderFactory.createMatteBorder(2,4,2,2,getBackground())); ValueSliderIcon.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { // Create a window with a slider and position the slider so the handle // matches up with the current mouse location. When user releases // mouse from click, mouse will be right on the handle. // Get the value int value; try { value = (int)Float.parseFloat(NodeValueJTextField.getText()); } catch (Exception ex) { value = 0; } // Get rid of any slider and death that's still around. if (SliderDeathTimer!=null) SliderDeathTimer.stop(); if (SliderWindow!=null) SliderWindow.dispose(); SliderWindow = new JWindow(); final JSlider slider = new JSlider(SwingConstants.VERTICAL,0,100,value); slider.setBorder(BorderFactory.createLineBorder(Color.black,1)); // Set up a change listener to allow slider to change node values. slider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent ce) { float value = slider.getValue(); NodeValueJTextField.setText(Float.toString(value)); TheModelState.updateNodeValue(CellIndex,TheNodeTemplate.getNodeNum(),value/100, (ModelStateChangeListener)SaveThis); } }); // Set up a mouse listener that will slider.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent me) { // If the SliderDeathTimer is running, kill it. if (SliderDeathTimer!=null) { SliderDeathTimer.stop(); SliderDeathTimer = null; } } public void mouseReleased(MouseEvent me) { // When user releases the mouse close the slider window. SliderWindow.dispose(); SliderWindow=null; } }); // Create a timer that kills of the window in case a niave user // brings it up and does nothing with it. SliderDeathTimer = new Timer(4000,new ActionListener() { public void actionPerformed(ActionEvent ae) { SliderWindow.dispose(); SliderWindow=null; SliderDeathTimer.stop(); SliderDeathTimer=null; } }); SliderDeathTimer.start(); SliderWindow.setContentPane(slider); SliderWindow.pack(); // Position the slider so habdle lines up with the mouse Point p = ValueSliderIcon.getLocationOnScreen(); p.x -= slider.getWidth()/2 - me.getX(); p.y -= (1.0-value/100.0)*slider.getHeight()-me.getY(); SliderWindow.setLocation(p); SliderWindow.setVisible(true); } }); add(ValueSliderIcon); } /** Returns the NodeTemplate that this panel displays @return NodeTemplate @author WJS */ public NodeTemplate getNodeTemplate() { return(TheNodeTemplate); } /** Sets the color of the Nodes ColorSwatch. @param Color color @author WJS */ public void setColor(Color color) { ColorSwatch.setBackground(color); } /** Sets the value of the initial value field for this NodePanel. Note that if the value is less than 0 it is set to blank. This occurrs when more than one cell is selected and the values are ambiguouse. @param float value - The new initial value. @author WJS */ public void setInitialValue(float value) { if (value<0) InitialNodeValueJTextField.setText(""); else { value = ((int)(value*10000))/100; InitialNodeValueJTextField.setText(Float.toString(value)); } } /** Sets the name of the node @param String name - Nmae for the node. @author WJS */ public void setName(String name) { NodeName.setText(name); } /** Sets the value of the value field for this NodePanel. Note that if the value is less than 0 it is set to blank. This occurrs when more than one cell is selected and the values are ambiguouse. @param float value - The new value. @author WJS */ public void setValue(float value) { if (value<0) NodeValueJTextField.setText(""); else { value = ((int)(value*10000))/100; NodeValueJTextField.setText(Float.toString(value)); } } /** Updates the node display values based upon the current values in its NodeTemplate. @author WJS */ public void updateTemplate() { setColor(TheNodeTemplate.getColor()); setName(TheNodeTemplate.getName()); // TODO - WHere is initial value stores? WHat is it? } } }