package genegui; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.Timer; import main.*; /** ModelStateNodePalette.java @author WJS */ public class ModelStateNodePalette extends JInternalFrame implements GuiInterface { /** The MainPanel holds all */ private JPanel MainPanel; /** An array of NodePanels, one for each Node type in the model */ private NodePanel[] NodePanels; /** A ScrollPane for scrolling through to-large a list of NodePanels */ private JScrollPane ScrollPane; /** 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 Main GUI */ private MainGui TheMainGui; /** The ModelState that this ModelStateNodePalette is attached to */ private ModelState TheModelState; /** Primary constructor builds the visual appearance for the palette and makes the menu bar. */ public ModelStateNodePalette(ModelState theModelState, MainGui theMainGui) { super("Node Palette",true,false,true,true); TheModelState = theModelState; TheMainGui = theMainGui; MainPanel = new JPanel(); MainPanel.setBackground(Color.lightGray); MainPanel.setLayout(new BoxLayout(MainPanel,BoxLayout.Y_AXIS)); ScrollPane = new JScrollPane(MainPanel); setContentPane(ScrollPane); // 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
  • visibilty control @author WJS */ private class NodePanel extends JPanel { /** THe color swatch for the displayed node color */ private JPanel ColorSwatch; /** A filler panel for pushing things up */ private JPanel Filler; /** The index of the node in the NodeDescriptor array of the ModelState */ private int Index; /** 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; /** A slider icon used for invoking a slider for easily changing the node value */ private JButton SliderIcon; /** THe NodeTemplate that this is attached to */ private NodeTemplate TheNodeTemplate; /** The icon used to indicate if this node is visible in the currently active ModelStateView */ private JToggleButton VisibleIcon; /** Constructore builds the visual appearance of the NodePanel and sets up listeners. @param NodeTemplate theNodeTemplate - THe NodeTemplate that this node panel is attched to. @author WJS */ public NodePanel(NodeTemplate theNodeTemplate) { super(); TheNodeTemplate = theNodeTemplate; Index = TheNodeTemplate.getNodeNum(); 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); // 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 JLabel ps = new JLabel("%"); 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(Index, value); } catch (NumberFormatException nfe) { System.err.println("ModeStateNodePaelette - Invalid number"); } } }); add(NodeValueJTextField); // Slider invoker SliderIcon = new JButton(new ImageIcon("icons/MSESliderIcon.gif")); SliderIcon.setDisabledIcon(new ImageIcon("icons/MSESliderIconDisabled.gif")); SliderIcon.setBorder(BorderFactory.createMatteBorder(2,4,2,2,getBackground())); SliderIcon.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { if (SliderIcon.isEnabled()) { // 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(Index, value); } }); // 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 = SliderIcon.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(SliderIcon); // Visibility control VisibleIcon = new JToggleButton(new ImageIcon("icons/MSEVisibleIconDisabled.gif")); VisibleIcon.setSelectedIcon(new ImageIcon("icons/MSEVisibleIcon.gif")); VisibleIcon.setContentAreaFilled(false); VisibleIcon.setBorder(BorderFactory.createMatteBorder(2,2,2,4,getBackground())); VisibleIcon.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { setEnabled(VisibleIcon.isSelected()); } }); add(VisibleIcon); setEnabled(false); } /** 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); } /** Enable/disabled controls. When enabled, the value field for the node can be changed. @param boolean enable - If true enables this panel. @author WJS */ public void setEnabled(boolean enable) { if (enable) { NodeName.setBackground(Color.white); NodeName.setBorder(BorderFactory.createMatteBorder(2,0,2,0,Color.white)); Filler.setBackground(Color.white); NodeValueJTextField.setBackground(Color.white); TheModelState.addStateChangeListener(TheModelState.getActiveModelStateView(),Index); } else { NodeName.setBackground(Color.lightGray); NodeName.setBorder(BorderFactory.createMatteBorder(2,0,2,0,Color.lightGray)); Filler.setBackground(Color.lightGray); NodeValueJTextField.setBackground(Color.lightGray); TheModelState.removeStateChangeListener(TheModelState.getActiveModelStateView(),Index); } NodeValueJTextField.setEnabled(enable); VisibleIcon.setSelected(enable); SliderIcon.setEnabled(enable); try { TheModelState.getActiveModelStateView().setNodeSelected(Index, enable); } catch (NullPointerException npe) { // Happens if user has no ModelStateViews open. no need to throw an error. } } /** Sets the icon of the node @param Icon icon - The ICon for the node. @author WJS */ public void setIcon(Icon icon) { NodeName.setIcon(icon); } /** 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*100))/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()); setIcon(TheNodeTemplate.getIcon()); setName(TheNodeTemplate.getName()); } } }