diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java index e99145e..0385b05 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationMenuBar.java @@ -17,6 +17,7 @@ import application.actions.OpenAction; import application.actions.SaveAction; import application.actions.SaveAsAction; +import application.actions.ShowNavigationAction; import application.actions.TreeLayoutAction; import application.actions.ZoomInAction; import application.actions.ZoomOutAction; @@ -25,7 +26,7 @@ public class ApplicationMenuBar extends JMenuBar { private static final long serialVersionUID = 4811536194182272888L; - private ApplicationWindow graphicalModelRefactor = null; + private ApplicationWindow applicationWindow = null; private NewResourceAction newResourceAction = null; private NewChannelAction newChannelAction = null; private NewIOChannelAction newIOChannelAction = null; @@ -37,47 +38,50 @@ private TreeLayoutAction treeLayoutAction = null; private CircleLayoutAction circleLayoutAction = null; - public ApplicationMenuBar(ApplicationWindow graphicalModelRefactor) { - this.graphicalModelRefactor = graphicalModelRefactor; + public ApplicationMenuBar(ApplicationWindow applicationWindow) { + this.applicationWindow = applicationWindow; JMenu newMenu = new JMenu("New"); - newMenu.add(new NewModelAction(graphicalModelRefactor)); + newMenu.add(new NewModelAction(applicationWindow)); - newMenu.add(newResourceAction = new NewResourceAction(graphicalModelRefactor.getEditor())); - newMenu.add(newChannelAction = new NewChannelAction(graphicalModelRefactor.getEditor())); - newMenu.add(newIOChannelAction = new NewIOChannelAction(graphicalModelRefactor.getEditor())); - newMenu.add(newFormulaChannelAction = new NewFormulaChannelAction(graphicalModelRefactor.getEditor())); + newMenu.add(newResourceAction = new NewResourceAction(applicationWindow.getEditor())); + newMenu.add(newChannelAction = new NewChannelAction(applicationWindow.getEditor())); + newMenu.add(newIOChannelAction = new NewIOChannelAction(applicationWindow.getEditor())); + newMenu.add(newFormulaChannelAction = new NewFormulaChannelAction(applicationWindow.getEditor())); JMenu menu = null; menu = add(new JMenu("File")); menu.add(newMenu); - menu.add(new OpenAction(graphicalModelRefactor)); + menu.add(new OpenAction(applicationWindow)); menu.addSeparator(); - menu.add(new SaveAction(graphicalModelRefactor)); - menu.add(new SaveAsAction(graphicalModelRefactor)); + menu.add(new SaveAction(applicationWindow)); + menu.add(new SaveAsAction(applicationWindow)); menu.addSeparator(); menu.add(new ExitAction()); menu = add(new JMenu("Edit")); - menu.add(deleteAction = new DeleteAction(graphicalModelRefactor.getEditor())); + menu.add(deleteAction = new DeleteAction(applicationWindow.getEditor())); menu = add(new JMenu("Layout")); - menu.add(dagLayoutAction = new DAGLayoutAction(graphicalModelRefactor.getEditor())); - menu.add(treeLayoutAction = new TreeLayoutAction(graphicalModelRefactor.getEditor())); - menu.add(circleLayoutAction = new CircleLayoutAction(graphicalModelRefactor.getEditor())); + menu.add(dagLayoutAction = new DAGLayoutAction(applicationWindow.getEditor())); + menu.add(treeLayoutAction = new TreeLayoutAction(applicationWindow.getEditor())); + menu.add(circleLayoutAction = new CircleLayoutAction(applicationWindow.getEditor())); menu = add(new JMenu("View")); - menu.add(new ZoomInAction(graphicalModelRefactor.getGraphComponent())); - menu.add(new ZoomOutAction(graphicalModelRefactor.getGraphComponent())); + menu.add(new ZoomInAction(applicationWindow.getGraphComponent())); + menu.add(new ZoomOutAction(applicationWindow.getGraphComponent())); menu = add(new JMenu("Generate")); - menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(graphicalModelRefactor.getEditor())); - menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(graphicalModelRefactor.getEditor())); + menu.add(javaPrototypeGenerateAction = new JavaPrototypeGenerateAction(applicationWindow.getEditor())); + menu.add(jerseyPrototypeGenerateAction = new JerseyPrototypeGenerateAction(applicationWindow.getEditor())); + + menu = add(new JMenu("Window")); + menu.add(new ShowNavigationAction(applicationWindow)); } public Editor getEditor() { - return graphicalModelRefactor.getEditor(); + return applicationWindow.getEditor(); } public void setEditor(Editor editor) { diff --git a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java index e53a9eb..e3fdbe6 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java +++ b/AlgebraicDataflowArchitectureModel/src/application/ApplicationWindow.java @@ -18,6 +18,7 @@ import application.editor.DataFlowCellEditor; import application.editor.Editor; +import application.views.NavigationWindow; public class ApplicationWindow extends JFrame { private static final long serialVersionUID = -8690140317781055614L; @@ -26,6 +27,7 @@ private Editor editor; private mxGraph graph; private ApplicationMenuBar menuBar; + private NavigationWindow navigationWindow; private mxGraphComponent graphComponent; public ApplicationWindow() { @@ -78,6 +80,10 @@ menuBar = new ApplicationMenuBar(this); setJMenuBar(menuBar); setSize(870, 640); + + navigationWindow = new NavigationWindow(this, editor); + navigationWindow.setVisible(true); + editor.addStageChangeListener(navigationWindow); } public mxGraph getGraph() { @@ -96,4 +102,8 @@ this.editor = editor; } + public void showNavigationWindow() { + navigationWindow.setVisible(true); + } + } diff --git a/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java new file mode 100644 index 0000000..ac58b48 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/actions/ShowNavigationAction.java @@ -0,0 +1,18 @@ +package application.actions; + +import java.awt.event.ActionEvent; + +import application.ApplicationWindow; + +public class ShowNavigationAction extends AbstractSystemAction { + + public ShowNavigationAction(ApplicationWindow frame) { + super("Show Navigation", frame); + } + + @Override + public void actionPerformed(ActionEvent e) { + frame.showNavigationWindow(); + } + +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java index bcf6326..82450a8 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/Editor.java @@ -70,6 +70,7 @@ protected Stage curStage = null; protected List stageQueue = null; + private List stageChangeListeners = null; protected String curFileName = null; protected String curFilePath = null; @@ -89,6 +90,7 @@ stageQueue.add(STAGE_PUSH_PULL_SELECTION); stageQueue.add(STAGE_CONTROL_FLOW_DELEGATION); curStage = STAGE_DATA_FLOW_MODELING; + stageChangeListeners = new ArrayList<>(); } public mxGraph getGraph() { @@ -104,6 +106,10 @@ return curStage; } + public boolean canChange(Stage nextStage) { + return nextStage.canChangeFrom(curStage); + } + public boolean nextStage() { int curStageNo = stageQueue.indexOf(curStage); if (curStageNo + 1 >= stageQueue.size()) return false; @@ -116,6 +122,16 @@ curStage = nextStage; return true; } + + public void addStageChangeListener(IStageChangeListener stageChangeListener) { + stageChangeListeners.add(stageChangeListener); + } + + private void notifyStageChangeListeners() { + for (IStageChangeListener l: stageChangeListeners) { + l.stageChanged(curStage); + } + } public DataFlowGraph getDataFlowGraph() { if (curStage instanceof PushPullSelectionStage) { @@ -152,6 +168,7 @@ model = null; ((DataFlowModelingStage) curStage).clear(); + notifyStageChangeListeners(); curFilePath = null; curFileName = null; @@ -184,7 +201,6 @@ ParserDTRAM parserDTRAM = new ParserDTRAM(new BufferedReader(new FileReader(file))); try { model = parserDTRAM.doParseModel(); - if (!Validation.checkUpdateConflict(model)) return null; if (curStage instanceof DataFlowModelingStage) { // Update the mxGraph. ((DataFlowModelingStage) curStage).setModel(model); @@ -194,6 +210,7 @@ // Change to the push/pull selection stage, analyze the data transfer model and construct a data-flow graph. changeStage(STAGE_PUSH_PULL_SELECTION); + notifyStageChangeListeners(); curFilePath = file.getAbsolutePath(); curFileName = file.getName(); @@ -221,7 +238,6 @@ Parser parser = new Parser(new BufferedReader(new FileReader(file))); try { model = parser.doParse(); - if (!Validation.checkUpdateConflict(model)) return null; if (curStage instanceof DataFlowModelingStage) { // Update the mxGraph. ((DataFlowModelingStage) curStage).setModel(model); @@ -231,6 +247,7 @@ // Change to the push/pull selection stage, analyze the data transfer model and construct a data-flow graph. changeStage(STAGE_PUSH_PULL_SELECTION); + notifyStageChangeListeners(); curFilePath = file.getAbsolutePath(); curFileName = file.getName(); @@ -381,6 +398,7 @@ ((DataFlowModelingStage) curStage).addIdentifierTemplate(res); model = ((DataFlowModelingStage) curStage).getModel(); + notifyStageChangeListeners(); } public void addChannelGenerator(DataTransferChannelGenerator channelGen) { @@ -390,6 +408,7 @@ ((DataFlowModelingStage) curStage).addChannelGenerator(channelGen); model = ((DataFlowModelingStage) curStage).getModel(); + notifyStageChangeListeners(); } public void addIOChannelGenerator(DataTransferChannelGenerator ioChannelGen) { @@ -399,6 +418,7 @@ ((DataFlowModelingStage) curStage).addIOChannelGenerator(ioChannelGen); model = ((DataFlowModelingStage) curStage).getModel(); + notifyStageChangeListeners(); } public void addFormulaChannelGenerator(FormulaChannelGenerator formulaChannelGen) { @@ -408,6 +428,7 @@ ((DataFlowModelingStage) curStage).addFormulaChannelGenerator(formulaChannelGen); model = ((DataFlowModelingStage) curStage).getModel(); + notifyStageChangeListeners(); } public boolean connectEdge(mxCell edge, mxCell src, mxCell dst) { @@ -415,7 +436,9 @@ boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); if (!stageChanged) return false; - return ((DataFlowModelingStage) curStage).connectEdge(edge, src, dst); + boolean isConnected = ((DataFlowModelingStage) curStage).connectEdge(edge, src, dst); + notifyStageChangeListeners(); + return isConnected; } public void delete() { @@ -424,12 +447,14 @@ if (!stageChanged) return; ((DataFlowModelingStage) curStage).delete(); + notifyStageChangeListeners(); } public void setChannelCode(DataTransferChannelGenerator ch, String code) { // Force to change to the data-flow modeling stage. boolean stageChanged = changeStage(STAGE_DATA_FLOW_MODELING); if (!stageChanged) return; + notifyStageChangeListeners(); ((DataFlowModelingStage) curStage).setChannelCode(ch, code); } diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java b/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java new file mode 100644 index 0000000..a345fe2 --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/IStageChangeListener.java @@ -0,0 +1,5 @@ +package application.editor; + +public interface IStageChangeListener { + public void stageChanged(Stage newStage); +} diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java index 7cb3d55..d1d92e9 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/DataFlowModelingStage.java @@ -9,6 +9,7 @@ import com.mxgraph.util.mxPoint; import com.mxgraph.view.mxGraph; +import algorithms.Validation; import application.editor.Stage; import application.editor.Editor; import application.editor.Editor.SrcDstAttribute; @@ -67,6 +68,12 @@ graph = constructGraph(graph, model); } + public boolean isValid() { + if (model == null) return false; + if (!Validation.checkUpdateConflict(model)) return false; + return true; + } + /** * Construct a mxGraph from DataFlowModel * @param model diff --git a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java index 540ca4e..3030100 100644 --- a/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java +++ b/AlgebraicDataflowArchitectureModel/src/application/editor/stages/PushPullSelectionStage.java @@ -22,8 +22,11 @@ @Override public boolean canChangeFrom(Stage prevStage) { - if (prevStage instanceof DataFlowModelingStage) return true; - if (((DataFlowModelingStage) prevStage).getModel() == null) return false; + if (prevStage instanceof DataFlowModelingStage) { + if (!((DataFlowModelingStage) prevStage).isValid()) return false; + return true; + } + if (prevStage instanceof ControlFlowDelegationStage) return true; return false; } diff --git a/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java b/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java new file mode 100644 index 0000000..6df73ca --- /dev/null +++ b/AlgebraicDataflowArchitectureModel/src/application/views/NavigationWindow.java @@ -0,0 +1,146 @@ +package application.views; + +import java.awt.Container; + +import javax.swing.ButtonGroup; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JToggleButton; +import javax.swing.GroupLayout.Group; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +import application.ApplicationWindow; +import application.editor.Editor; +import application.editor.IStageChangeListener; +import application.editor.Stage; +import application.editor.stages.ControlFlowDelegationStage; +import application.editor.stages.DataFlowModelingStage; +import application.editor.stages.PushPullSelectionStage; + +public class NavigationWindow extends JDialog implements IStageChangeListener { + private String title = "Navigation"; + private Editor editor; + private JToggleButton dataFlowModelingButton; + private JToggleButton pushPullSelectionButton; + private JToggleButton controlFlowDelegationButton; + + public NavigationWindow(ApplicationWindow owner, Editor editor) { + super(owner); + setTitle(title); + setDefaultCloseOperation(HIDE_ON_CLOSE); + this.editor = editor; + Container panel = getContentPane(); + panel.setLayout(new java.awt.GridLayout(3, 1)); + dataFlowModelingButton = new JToggleButton("Data-Flow Modeling"); + pushPullSelectionButton = new JToggleButton("PUSH/PULL Selection"); + controlFlowDelegationButton = new JToggleButton("Control-Flow Delegation"); + dataFlowModelingButton.addChangeListener(new DataFlowModelingButtonListener()); + pushPullSelectionButton.addChangeListener(new PushPullSelectionButtonListener()); + controlFlowDelegationButton.addChangeListener(new ControlFlowDelegationButtonListener()); + ButtonGroup group = new ButtonGroup(); + group.add(dataFlowModelingButton); + group.add(pushPullSelectionButton); + group.add(controlFlowDelegationButton); + panel.add(dataFlowModelingButton); + panel.add(pushPullSelectionButton); + panel.add(controlFlowDelegationButton); + controlFlowDelegationButton.setEnabled(false); + dataFlowModelingButton.setEnabled(false); + dataFlowModelingButton.setSelected(true); + pack(); + setResizable(false); + } + + @Override + public void stageChanged(Stage newStage) { + if (newStage instanceof DataFlowModelingStage) { + dataFlowModelingButton.setSelected(true); + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } else if (newStage instanceof PushPullSelectionStage) { + pushPullSelectionButton.setSelected(true); + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } else if (newStage instanceof ControlFlowDelegationStage) { + controlFlowDelegationButton.setSelected(true); + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + } + } + + private class DataFlowModelingButtonListener implements ChangeListener { + @Override + public void stateChanged(ChangeEvent e) { + editor.changeStage(Editor.STAGE_DATA_FLOW_MODELING); + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } + } + + private class PushPullSelectionButtonListener implements ChangeListener { + @Override + public void stateChanged(ChangeEvent e) { + editor.changeStage(Editor.STAGE_PUSH_PULL_SELECTION); + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_CONTROL_FLOW_DELEGATION)) { + controlFlowDelegationButton.setEnabled(true); + } else { + controlFlowDelegationButton.setEnabled(false); + } + } + } + + private class ControlFlowDelegationButtonListener implements ChangeListener { + @Override + public void stateChanged(ChangeEvent e) { + editor.changeStage(Editor.STAGE_CONTROL_FLOW_DELEGATION); + if (editor.canChange(Editor.STAGE_DATA_FLOW_MODELING)) { + dataFlowModelingButton.setEnabled(true); + } else { + dataFlowModelingButton.setEnabled(false); + } + if (editor.canChange(Editor.STAGE_PUSH_PULL_SELECTION)) { + pushPullSelectionButton.setEnabled(true); + } else { + pushPullSelectionButton.setEnabled(false); + } + } + } +}