package visualisation; import logging.Algorithm; import logging.LogElement; import logging.LogElementList; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; /** * This is the central class for using packages logging and visualization. * It contains each an area for graphical and textual output of an algorithm step and an area for parameter input. * Use it in an application or as an applet. * If you use it as an applet you will have to extend it by a standard constructor that creates your applet. * @see logging.Algorithm * @see LogElement * @see LogElementList * @see DrawArea * @see ParameterArea * @see TextArea * @see LegendArea * @see JApplet * @author Bj�rn Strobel
* University of Cooperative Education Stuttgart, * Campus Horb
* Department of Information Technology
* it2003
*/ public class HybridWindow< DRAW extends DrawArea, TEXT extends TextArea, PARAM extends ParameterArea, ALGORITHM extends Algorithm, LOG extends LogElement, LEGEND extends LegendArea > extends JApplet{ /** Constant representing state of parameter input. */ final protected byte PARAMETERSTATE=0; /** Constant representing state of activated algorithm. */ final protected byte RUNSTATE=1; /** Constant representing state of automatic stepping. */ final protected byte AUTOSTATE=2; /** Represents the current state of this application. */ protected byte state; /** The window's draw area for graphical output of an algorithm step.*/ protected DRAW drawArea; /** The window's text area for textual output of an algorithm step.*/ protected TEXT textArea; /** The window's parameter area for parameter input of an algorithm. */ protected PARAM parameterArea; /** The presented algorithm. */ protected ALGORITHM algorithm; /** Log element list containing the algorithm's single step's log elements. */ protected LogElementListlogList; /** The window's legend area for describing the parameters of an algorithm's graphical output. */ protected LEGEND legendArea; /** The hybrid window's tabbed pane containing the draw area. */ protected JTabbedPane tabbedPane; /** The window's start button. Triggers algorithm processing.*/ protected JButton startButton; /** The window's stop button. Clears the window for a new parametric input. */ protected JButton stopButton; /** The window's next button. Proceeds to next log element. */ protected JButton nextButton; /** The window's previous button. Proceeds to previous log element. */ protected JButton prevButton; /** The window's last button. Proceeds to last log element. */ protected JButton lastButton; /** The window's first button. Proceeds to first log element. */ protected JButton firstButton; /** The window's toggle button for automatic proceeding. Enables/Disables automatic step processing. */ protected JToggleButton autoButton; /** The window's toggle button for pausing automatic proceeding. */ protected JButton pauseButton; /** The window's delay slider for automatic proceeding. Adjusts the interval of auto stepping. */ protected JSlider autoSlider; /** The window's radio button for forward direction at auto stepping. */ protected JRadioButton autoForwardButton; /** The window's radio button for backward direction at auto stepping. */ protected JRadioButton autoBackwardButton; /** Action listener for start button. */ protected StartListener startListener; /** Action listener for stop button. */ protected StopListener stopListener; /** Action listener for previous button. */ protected PrevListener prevListener; /** Action listener for next button. */ protected NextListener nextListener; /** Action listener for first button. */ protected FirstListener firstListener; /** Action listener for last button. */ protected LastListener lastListener; /** Item listener for auto button. */ protected AutoButtonListener autoButtonListener; /** Change listener for auto slider. */ protected AutoSliderListener autoSliderListener; /** Item listener for forward button. */ protected AutoForwardListener autoForwardListener; /** Item listener for backward button. */ protected AutoBackwardListener autoBackwardListener; /** Item listener for pause button. */ protected PauseButtonListener pauseButtonListener; /** Timer for auto stepping. */ protected Timer autoTimer; /** * Standard constructor. */ public HybridWindow() { tabbedPane=new JTabbedPane(); } /** * Extended constructor. Types of drawArea, textArea, parameterArea, algorithm and logList are determined here. * @param drawArea the window's draw area. It must extend visualization.DrawArea. * @param textArea the window's text area. It must extend visualization.TextArea. * @param parameterArea the window's parameter area. It must extend visualization.ParameterArea. * @param algorithm the window's algorithm. It must extend logging.Algorithm. * @param logList the window's log list. Elements must extend logging.LogElement. * @param legendArea the window's legend area. Must be a subclass of visualization.LegendArea */ public HybridWindow(DRAW drawArea, TEXT textArea, PARAM parameterArea, ALGORITHM algorithm, LogElementListlogList, LEGEND legendArea) { this.drawArea=drawArea; this.textArea=textArea; this.parameterArea=parameterArea; this.algorithm=algorithm; this.logList=logList; this.legendArea=legendArea; tabbedPane=new JTabbedPane(); } /** * Applet's initial phase. * In case of use as an application call it explicitely. * Sets up the GUI and the action listeners. */ public void init(){ startButton=new JButton("start"); stopButton=new JButton("stop"); nextButton=new JButton("next"); prevButton=new JButton("prev"); lastButton=new JButton("last"); firstButton=new JButton("first"); autoButton=new JToggleButton("automatc"); autoSlider=new JSlider(1,100,1); autoForwardButton=new JRadioButton("forward"); autoBackwardButton=new JRadioButton("backward"); pauseButton=new JButton("pause"); ButtonGroup autoDirection=new ButtonGroup(); autoDirection.add(autoForwardButton); autoDirection.add(autoBackwardButton); autoForwardButton.setSelected(true); JPanel panelStartStopControls=new JPanel(); panelStartStopControls.setLayout(new GridLayout(4,1,5,5)); panelStartStopControls.add(startButton); panelStartStopControls.add(stopButton); panelStartStopControls.add(pauseButton); panelStartStopControls.setBorder(BorderFactory.createTitledBorder("Start / Stop")); JPanel panelStepwiseExecutionControls=new JPanel(); panelStepwiseExecutionControls.setLayout(new GridLayout(4,1,5,5)); panelStepwiseExecutionControls.add(firstButton); panelStepwiseExecutionControls.add(nextButton); panelStepwiseExecutionControls.add(prevButton); panelStepwiseExecutionControls.add(lastButton); panelStepwiseExecutionControls.setBorder(BorderFactory.createTitledBorder("Stepwise execution")); JPanel panelAutomaticExecutionControls=new JPanel(); panelAutomaticExecutionControls.setLayout(new GridLayout(5,1,5,5)); panelAutomaticExecutionControls.add(autoButton); panelAutomaticExecutionControls.add(autoSlider); panelAutomaticExecutionControls.add(autoForwardButton); panelAutomaticExecutionControls.add(autoBackwardButton); panelAutomaticExecutionControls.setBorder(BorderFactory.createTitledBorder("Automatic execution")); JPanel buttonLine=new JPanel(); buttonLine.setLayout(new GridLayout(3,1,5,5)); buttonLine.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); buttonLine.add(panelStartStopControls); buttonLine.add(panelStepwiseExecutionControls); buttonLine.add(panelAutomaticExecutionControls); JLabel headline=new JLabel(algorithm.getTitle()); headline.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); headline.setFont(new Font("SansSerif",Font.PLAIN,20)); JScrollPane parameterAreaScrollPane = parameterArea.getScrollPane(); JScrollPane legendAreaScrollPane = legendArea.getScrollPane(); parameterAreaScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); legendAreaScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); JSplitPane hybridWindowSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,parameterAreaScrollPane, legendAreaScrollPane); hybridWindowSplitPane.setOneTouchExpandable(true); hybridWindowSplitPane.setResizeWeight(0.465); tabbedPane.insertTab(drawArea.getDrawAreaName(),null, drawArea.getScrollPane(),drawArea.getDrawAreaName(),0); tabbedPane.setSelectedIndex(0); setLayout(new BorderLayout(10,10)); add(headline,BorderLayout.NORTH); add(hybridWindowSplitPane,BorderLayout.WEST); add(tabbedPane,BorderLayout.CENTER); add(textArea.getScrollPane(),BorderLayout.SOUTH); add(buttonLine,BorderLayout.EAST); setState(PARAMETERSTATE); startListener=new StartListener(); stopListener=new StopListener(); prevListener=new PrevListener(); nextListener=new NextListener(); firstListener=new FirstListener(); lastListener=new LastListener(); autoButtonListener=new AutoButtonListener(); autoSliderListener=new AutoSliderListener(); autoForwardListener=new AutoForwardListener(); autoBackwardListener=new AutoBackwardListener(); pauseButtonListener=new PauseButtonListener(); startButton.addActionListener(startListener); stopButton.addActionListener(stopListener); prevButton.addActionListener(prevListener); nextButton.addActionListener(nextListener); firstButton.addActionListener(firstListener); lastButton.addActionListener(lastListener); autoButton.addItemListener(autoButtonListener); autoSlider.addChangeListener(autoSliderListener); autoForwardButton.addItemListener(autoForwardListener); autoBackwardButton.addItemListener(autoBackwardListener); pauseButton.addActionListener(pauseButtonListener); autoTimer=new Timer(1,nextListener); } /** * Sets the window's state and enables/disables the corresponding components. * @param state */ final protected void setState(int state){ Component[]components=parameterArea.getComponents(); switch(state){ case PARAMETERSTATE: state=PARAMETERSTATE; for(Component c:components){ c.setEnabled(true); } startButton.setEnabled(true); stopButton.setEnabled(false); nextButton.setEnabled(false); prevButton.setEnabled(false); lastButton.setEnabled(false); firstButton.setEnabled(false); autoButton.setEnabled(false); autoSlider.setEnabled(false); autoForwardButton.setEnabled(false); autoBackwardButton.setEnabled(false); pauseButton.setEnabled(false); break; case RUNSTATE: state=RUNSTATE; for(Component c:components){ c.setEnabled(false); } startButton.setEnabled(false); stopButton.setEnabled(true); nextButton.setEnabled(true); prevButton.setEnabled(true); lastButton.setEnabled(true); firstButton.setEnabled(true); autoButton.setEnabled(true); autoSlider.setEnabled(true); autoForwardButton.setEnabled(true); autoBackwardButton.setEnabled(true); pauseButton.setEnabled(false); break; case AUTOSTATE: state=AUTOSTATE; for(Component c:components){ c.setEnabled(false); } startButton.setEnabled(false); stopButton.setEnabled(false); nextButton.setEnabled(false); prevButton.setEnabled(false); lastButton.setEnabled(false); firstButton.setEnabled(false); autoButton.setEnabled(true); autoSlider.setEnabled(true); autoForwardButton.setEnabled(true); autoBackwardButton.setEnabled(true); pauseButton.setEnabled(true); break; } } /** * Returns the window's current state. * @return the window's current state */ final protected byte getState(){ return state; } /** * Method for adding a new component to the hybrid window's tabbed pane * @param title the title of the new tab * @param component the component to be added to the tabbed pane */ final public void addNewComponent(String title,Component component){ tabbedPane.addTab(title,component); } /** * Method for adding a new component to the hybrid window's tabbed pane * @param title the title of the new tab * @param icon the icon to be displayed on the new tab * @param component the component to be added to the tabbed pane */ final public void addNewComponentWithIcon(String title,Icon icon,Component component){ tabbedPane.addTab(title,icon,component); } class StartListener implements ActionListener{ public void actionPerformed(ActionEvent event){ setState(RUNSTATE); logList=algorithm.run(); drawArea.setLogList(logList); textArea.setLogList(logList); } } class StopListener implements ActionListener{ public void actionPerformed(ActionEvent event){ setState(PARAMETERSTATE); logList.clear(); drawArea.clear(); textArea.clear(); } } class PrevListener implements ActionListener{ public void actionPerformed(ActionEvent event){ if(logList.isInitialized()){ if(logList.get()==logList.firstElement()){ autoButton.setSelected(false); } else{ logList.prev(); drawArea.drawStep(); textArea.printStep(); } } else{ logList.prev(); drawArea.drawStep(); textArea.printStep(); } } } class NextListener implements ActionListener{ public void actionPerformed(ActionEvent event){ if(logList.isInitialized()){ if(logList.get()==logList.lastElement()){ autoButton.setSelected(false); } else{ logList.next(); drawArea.drawStep(); textArea.printStep(); } } else{ logList.next(); drawArea.drawStep(); textArea.printStep(); } } } class FirstListener implements ActionListener{ public void actionPerformed(ActionEvent event){ logList.first(); drawArea.drawStep(); textArea.printStep(); } } class LastListener implements ActionListener{ public void actionPerformed(ActionEvent event){ logList.last(); drawArea.drawStep(); textArea.printStep(); } } class AutoButtonListener implements ItemListener{ public void itemStateChanged(ItemEvent event){ if(event.getStateChange()==ItemEvent.SELECTED){ setState(AUTOSTATE); autoTimer.setDelay(10000/((int)Math.pow(autoSlider.getValue(),2))); autoTimer.start(); }else{ setState(RUNSTATE); autoTimer.stop(); } } } class AutoSliderListener implements ChangeListener{ public void stateChanged(ChangeEvent event){ if(autoTimer.isRunning()){ autoTimer.stop(); autoTimer.setInitialDelay(10000/((int)Math.pow(autoSlider.getValue(),2))); autoTimer.setDelay(10000/((int)Math.pow(autoSlider.getValue(),2))); autoTimer.start(); autoTimer.setInitialDelay(1); } } } class AutoForwardListener implements ItemListener{ public void itemStateChanged(ItemEvent event){ if(event.getStateChange()==ItemEvent.SELECTED){ autoTimer.removeActionListener(prevListener); autoTimer.addActionListener(nextListener); } } } class AutoBackwardListener implements ItemListener{ public void itemStateChanged(ItemEvent event){ if(event.getStateChange()==ItemEvent.SELECTED){ autoTimer.removeActionListener(nextListener); autoTimer.addActionListener(prevListener); } } } class PauseButtonListener implements ActionListener{ public void actionPerformed(ActionEvent event){ if(autoButton.isSelected()){ setState(RUNSTATE); autoTimer.stop(); autoButton.setSelected(false); } } } }