ProjektGraph/visualisation/HybridWindow.java

490 lines
16 KiB
Java
Raw Normal View History

2024-06-27 09:07:46 +00:00
package visualisation;
import java.lang.Math;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToggleButton;
import javax.swing.ScrollPaneConstants;
import javax.swing.Timer;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import logging.Algorithm;
import logging.LogElement;
import logging.LogElementList;
/**
* 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 logging.LogElement
* @see logging.LogElementList
2024-06-27 09:07:46 +00:00
* @see DrawArea
* @see ParameterArea
* @see TextArea
* @see LegendArea
* @see javax.swing.JApplet
2024-06-27 09:07:46 +00:00
* @author Bj<EFBFBD>rn Strobel<br><small>
* University of Cooperative Education Stuttgart,
* Campus Horb<br>
* Department of Information Technology<br>
* it2003<br></small>
*/
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 LogElementList<LOG>logList;
/** 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,LogElementList<LOG>logList,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);
}
}
}
}