2019/10/21 Assignment 3
Assignment 3
Due 1 Nov by 23:59 Points 13
Event Driven Computing 2019 Assignment 3 FSA Editor
Last chance to submit 11:59pm, Friday 8th of November 2019 This assignment is worth of 13% of the total course mark.
1. Summary
In this assignment, you will build a complete graphical FSA Editor, in a class called FsaEditor , that permits editing of FSAs.
The Fsa that you display will be stored in the FsaImpl class you wrote for assignment 2. Your FsaEditor program can read an Fsa from a file, or write one to a file, using the FsaReaderWriter class you built previously.
2. Specification
We recommend that you build the program in a series of steps, as described here. Test carefully after each step to ensure your code is working. Finding bugs later is much more difficult and time-consuming
Exercise 1 Building the GUI
Your GUI will have a main panel, that displays a representation of the Fsa you are editing. There will be a control-bar at the bottom of the window, to allow you to simulate operation of the Fsa. There will also be a menu-bar, containing two items, to allow the user to control the program:
A File menu that contains the options: Open, Save as, and Quit.
The Open item pops up a file dialogue ( JFileChooser ), and allows a user to choose an Fsa file to read in and display. Any existing fsa on the display is discarded. If the file contains errors, a pop-up box displays the error message, and the display shows all data read prior to the error.
The Save as item pops up a file dialogue ( JFileChooser ), and allows a user to choose a file, or enter a filename into which will be written a representation of the Fsa. If an error occurs during writing, a pop-up box shows the error message. Note: The default file-extension for all Fsa files is .fsa.
The Quit item allows a user to quit the program.
An Edit menu that contains the options: New state, New transition, Set initial, Unset initial, Set final, Unset final, and Delete. These option are described in more detail below.
You should also add a keyboard shortcut for each file-menu item (see JMenuItem.setAccelerator() ). These are:
File->Open: Control-O File->Save as: Control-S
file:///Users/lyt/Desktop/Assignment3.htm
1/9
2019/10/21 Assignment 3
File->Quit: Control-Q
Attach a listener to the Quit item that will cause your program to quit. Attach liteners to the other menu items that (for the moment) simply prints out a message such as Open selected, when that menu item is selected.
Exercise 2 Verify the basics
You should build all of the above parts in a class named FsaEditor , and then verify that each part is working before proceeding. Your FsaEditor class should contain a main method so that your program can be executed. Verify that all the menu items function correctly, and that they print out the expected message. Verify that Quit causes the program to quit.
Do not proceed until you have verified all is well!
Exercise 3 Reading and writing files
Extend your program so that the Open , and Save as menu items correctly open and save, fsa files. You should use the FsaImpl and FsaReaderWriter classes you wrote for practical to do this job. Make certain that the program can save and restore files in the current directory (the directory from which the program was loaded)! If an exception is thrown by the FsaReaderWriter code, your program should pop up a dialogue box ( JDialog ) that displays the error message, and then allow the user to press an Ok button to dismiss it.
Exercise 4 Verify reading and writing
Once again, test throroughly. Open a file, and verify that you can successfully save it again. Check that the result is the same as the file you loaded (except for the ordering of records, of course). Read in a file that has errors, and check that the error dialogue pops up and can be dismissed. After an error, verify that you can still open another file correctly.
Time spent testing here will save a lot of grief later Do not proceed until you have verified all is well!
Exercise 5 Build the fsa panel
Create a new class, named , that extends JPanel and implements FsaListener , and add it to the main JFrame of your . Important: Make sure that the layout manager for this panel is set to null , or you will experience a lot of strange behaviour later on. FsaPanel will need to implement the three methods of the FsaListener interface. For the moment, each of the three methods should simply print out a message that says something like statesChanged, when the method is called.
Exercise 6 Test the FsaListener
Test your program, similarly to Exercise 4, by reading in files. Each time the reader-writer adds a place to your FsaImpl , you should find that the FsaListener you have implemented gets called, and prints its message. For example, if the file you open contains four states, there should be four calls to statesChanged printed out. Similarly there should be a call to transitionsChanged , each time a transition is added.
Note that through all these tests, the FsaPanel will be blank, since nothing has been added to it yet. Dont worry, thats coming soon!
Do not proceed until you have verified all is well!
Exercise 7 Creating the StateIcon
FsaPanel
FsaEditor
file:///Users/lyt/Desktop/Assignment3.htm
2/9
2019/10/21 Assignment 3
Build a new class named that extends , and implements . This class will be used to display a state on the screen. You will need to override the method, to make the paint a coloured circle on the screen.
Exercise 8 Testing the StateIcon
The easist way to test the , is to temporarily add some code to the constructor of the
class, so that it directly adds a to the panel, at a known location (such as 20,30). When you execute the program you should then see the circle that you have drawn. You may need to do some debugging here if not. If all is well, add a few more StateIcons, positioned at other locations on the screen, to check that the program can handle multiple StateIcons on the screen at once.
Do not proceed until you have verified all is well!
Exercise 9 Displaying states
Modify the method in the so that each time it is called it calls the underlying
to find out what states have changed. To do this you will need to compare the list of states in the
FsaImpl (returned by getStates()), with a list of states stored in your FsaPanel. (Youll probably need to add an instance variable to help with this.) Build code in your StateListener so that whenever a new state (say p) is added, your program:
StateIcon
JComponent
StateListener
paintComponent
StateIcon
StateIcon
FsaPanel
StateIcon
statesChanged
FsaPanel
FsaImpl
StateIcon
p
stateChanged
StateIcon
p
1. Creates a new
2. Arranges that the
coordinates of the state
3. Adds the state Icon to the FsaPanel , so it will be displayed.
Note: For each state, there will be a corresponding StateIcon registered as a listener of that state. Each StateIcon will need to keep a pointer to its underlying State, so that it can get information from the state (such as its (x, y) position on the screen). In future, whenever the state changes, your StateIcon will receive a call to stateChanged that tells it about the change. This should mean that the display is automatically updated when the state changes.
You will need to add code to your StateIcon.paintComponent method so that it can distinguish an ordinary state from an initial state or a final state. (Remember that a state can be both an initial and a final state at the same time!)
You can test this by writing some code that calls the moveBy, setInitial, and setFinal methods for the underlying state, to change the values in it. Each time you do this, the position or appearance of the state on the screen should change.
Do not proceed until you have verified all is well!
Exercise 10 Verify that the StateIcons appear
Once again, read in a file, as in Exercise 4. You already know that each time a state is added your statesChanged method will be called (verified in Exercise 6). Now, with the new code you have added, you should find that your program displays a new icon for each new state. Neat, isnt it! Remember that the essence of testing is simplicity first. The first file you test should have just one state in it. When that works correctly, then you can try more complex files!
Do not proceed until you have verified all is well!
, and adds the StateIcon as a listener to .
method in the state icon sets the location of the to the
, and then calls repaint.
file:///Users/lyt/Desktop/Assignment3.htm 3/9
2019/10/21
Exercise 11 Adding mouse actions
Modify the class so that it adds a You will need to implement seven methods:
, mouseMoved , and says something like mousePressed.
Exercise 12 Check that the MouseListener works
Compile and execute your program, and verify that when the mouse is pressed clicked, dragged, released, etc in the FsaPanel, the appropriate message is printed.
Do not proceed until you have verified all is well!
Exercise 13 Adding selection option to a StateIcon
Modify the StateIcon code so that it includes a boolean field named isSelected. Modify the mouseListener code so that when the mouse is clicked on an icon, the selected field is flipped from false to true or from true to false. Change the paintComponent method so that you can see the state of this variable, by painting a filled circle when the state is selected, and an outline circle when it is not.
Exercise 14 Verify that selection works
Read in an Fsa containing several states. Click the mouse on the states, and verify that you are able to select and de-select individual states, and that each time you do so the icon changes. (Hint: If this doesnt happen, try resizing the window a little bit. If doing so makes the display show correctly, then you know you need to add a call to repaint to your program.) Do not proceed until you have verified all is well!
Exercise 15 Set/unset start and end states
Add an item to the Edit menu that allows a user to Set initial state.
To use this option, a user first selects one (or more) a states (by clicking on it/them), and then chooses the menu option set initial state.
The program should set each of the the selected state(s) as an initial state, by calling setInitial(true) in the corresponding StateImpl. This in turn shoul call setInitial(true) in the underlying state. You can find the icons that are selected by iterating over all the StateIcon objects.
If your StateImpl and listners are working correctly (as tested in Exercise 9 above), you will not need to do anything more to make the display update, because the StateListener for the selected state will automatically notify the corresponding StateIcon. If you have not done it earlier, you will need to add some code to the StateIcon.paintComponent method to display a lightning strike to show an initial state.
Add a menu item Set final state, that behaves similarly to Set initial state. (It will call setFinal, of course) You will also need to make sure the StateIcon correctly displays a double-circle to indicate a final state. Add a menu item unset initial state, that unsets an initial state. Add a menu item unset final state, that unsets a final state. Both of these operations should be almost trivial, now that everything else is working.
Exercise 16 Adding a selection box to FsaPanel
The next step is to add code that allows the user to drag a selection box on the screen to select multiple states. The best way to do this is to build a finite state machine. You will find that you need this FSM to
Assignment 3
FsaPanel
mouseReleased
MouseListener
mouseDragged
mouseEntered
mouseExited
mousePressed
mouseClicked
JComponent
and a mouseMotionListener to the . ,
,
. Simply make each method-body print a trivial message that
file:///Users/lyt/Desktop/Assignment3.htm 4/9
2019/10/21 Assignment 3
implement other stages of the program, so build it now. The outline of the core parts of the machine is show in this diagram:
Build the core of the machine (state variable, state-name variables, etc) but dont try to build the rest of the machine all at once. We will begin by building the idle and selecting states. As the diagram shows, the machine begins in the idle state. When the mouse is pressed and the (x, y) position of the mouse is over the background, the machine sets isSelected to false for all the icons, remembers the starting coordinate as (x0, y0), and transitions to the selecting state. In the selecting state, if the mouse is released, the machine returns to the idle state. However, if the mouse is dragged, the machine causes a rectangle to be displayed on the screen, from (x0, y0), to the current position (x, y). (To get the rectangle to draw, youll need to call repaint, and then in the paintComponent method, actually draw the rectangle.)
Implement this code, then test it. If it is working correctly you should find that when you click the mouse and drag it to the right and down, your program draws a selection-rectangle on the screen that follows the mouse pointer. If you drag to the left or upwards, you will find that the box is not drawn on the screen, because the Rectangle class wont display a rectangle with negative width or height. You will need to add some extra code so that selection works correctly in these cases. When you release the mouse, the rectangle should disappear.
Do not proceed until you have verified all is well!
Exercise 17 Making the selection box work
Now that you can draw a selection box, we need to make it work correctly. Each time the mouseDragged method is called, check to see if the selection-box intersects any of the components of the FsaPanel. You can get all the components by calling getComponents. You can check for intersection using the rectangle.intersects() method and the getBounds() method of the component. If you find a component that is inside the selection rectangle, set the icons isSelected flag to true. If the component doesnt intersect the selection rectangle, set its isSelected flag to false. The effect of this should be that when you drag the selection rectangle over state icons, the ones inside the rectangle are displayed as selected, and the ones
file:///Users/lyt/Desktop/Assignment3.htm
5/9
2019/10/21 Assignment 3
outside are displayed as not selected. If your previous code is correct, you will not need to add any code to make the states display correctly the repaints should occur automatically.
Do not proceed until you have verified all is well!
Exercise 18 Dragging multiple states
Add a another state to the FSM, named dragging. In the idle state, if the mouse is pressed, and the (x, y) location is above a StateIcon, the user may be is attempting to move a state. If the icon under the mouse is presently not selected, deselect all icons, then select the icon under the mouse, other wise do nothing. (This change to the code will preserve the behaviour of clicking on a state to select it.) Remember the starting locaton as (x0, y0), and transition to the dragging state. In the dragging state, if the mouse is released, simply return to the idle state. If the mouse is dragged, all selected icons should be moved by calling the moveBy method to move them a distance (x x0, y y0). Update (x0, y0) to be (x, y). Now, if you click-drag the mouse to select several states, then click on an unselected state, you should find that just that state becomes selected. If you click-drag the mouse to select several states, then click-drag on one of the selected states, all the states should move.
Do not proceed until you have verified all is well!
Exercise 19 Displaying transitions
Build a new class named TransitionIcon that extends , and implements . This class will be used to display a transition on the screen. and will operate very similarly to StateIcon and StateImpl , so you may be able to cut and paste quite a lot of the code.
You will need to override the paintComponent method, to make the TransitionIcon draw a line between the two states, and to draw text that shows the name of the event (in the middle of the transition).
Similar to the FSAs weve seen so far, the transitions should use a curved line, but you can start with straight lines if needed.
To implement a curved line, you should probably use a QuadCurve2D for this. Heres a diagram that shows the basic mathematics.
JComponent
TransitionListener
TransitionIcon
TransitionImpl
file:///Users/lyt/Desktop/Assignment3.htm
6/9
2019/10/21 Assignment 3
The two States are located at (x1, y1), and (x2, y2). We can readily compute the mid-point of the line that joins the states, (xm, ym), and the point where the line intersects each circle, (xb1, yb1) and (xb2, yb2). We construct a line of length d, at right-angles to the line of centres, through (xm, ym), and thus find (xc, yc). All the mathemtics can be done using similar triangles, and involves only simple arithmetic. There is no need for trigonometry.
When done correctly, the solution automatically works for any orientation of the two states. (No need for lots of special cases!) To draw transition, use a QuadCurve2D, starting at (xb1, yb1), ending at (xb2, yb2), and with control point (xc, yc). Using similar maths, you can draw an arrow-head on the end that always points towards the centre of the state.
Modify the FsaPanel so that the method adds a TransitionIcon to the FsaPanel whenever a Transition is added to the underlying .
You can test your implementation by reading in a file that has two States and one Transition. The states should display correctly, because of the testing you have done before. If all is well, your TransitionIcon will correctly display the transition on the screen.
Do not proceed until you have verified all is well!
Exercise 20 Verifying transitions work
Make a small file that has three states and three transitions. Load it into your editor and display it. If all is well, there will be three states and three transitions showing. Now click-drag on one of the states and move it on the screen. If all is well, the state will move (because you verified this behaviour earlier), and the transition will move also (because the TransitionListener is called whenever one of the state moves.) If it does not, theres probably an error in your FsaImpl, where the Transition is not calling transitionChanged when either of the end-points of the transition moves.
Exercise 21 Adding a new state
Add an entry Add state to the Edit menu that allows a user to add a new state. When the user selects this menu item, display a dialogue (use JDialog) that asks the user for the name of the state, and offers ok and cancel options. If the user presses cancel, the operation is cancelled. If the user presses ok, the program calls the FsaImpl.addState method to create it. The initial (x, y) location should be the same as the position of the mouse. The listener mechanisms that you have built and tested earlier will automatically create and display the corresponding icon on the screen. If there is an error (e.g. the name is illegal,or the state already exists), your program should display a dialog showing the error message, wait until the user clicksok, and then ignore the operation. The display now shows a new state at the location of the mouse cursor on the screen. As the mouse moves about, move the state with it. (Just call the moveBy method for the state, and the icon will magically follow!) To place the new state, the user clicks the mouse-button, and the state then remains at the current location on the screen. To implement the above behaviour, you will need to add one or more states to your control-FSM. If you have done this correctly, you will find that all your previous mouse-handling code is still working correctly. (Thats the great advantage of using an FSM!) You should verify that the state has been added correctly by saving the modified fsa to a file, and checking that the new state is in the file.
Exercise 22 Adding a new transition
Add an entry addTransition to the Edit menu that allows a user to add a new transition, that works very similarly to add state. When the user selects this menu item, a dialogue should pop up to ask the user for
transitionsChanged()
FsaImpl
file:///Users/lyt/Desktop/Assignment3.htm
7/9
2019/10/21 Assignment 3
the name of the event and offer ok and cancel options. If the user presses cancel, the operation is cancelled. If the user presses ok, the program chages the mouse-cursor to a cross, and waits for the user to click on two states, that represent the start and end of the transition. When the user clicks on the first state, the display shows a rubber-band line, beginning at the first state and continuing to the mouse-pointer. As the mouse moves about this line lengthens and shortens. When the user clicks on the second state, the rubber- band line disappears, and the program attempts to create a new transition, between the two states. To create a new transition, you need only add the transition to the FsaImpl. If an error occurs (the name is invalid, or a transition with this name already exists, the program displays an error dialog, and waits for the user to click ok. If all is well, the transition will magically appear on the display, because the listener mechanism that you have built and tested earlier will create and display the icon. As in addState, you will need to add state(s) to your control-Fsm to implement this behaviour. You can verify that the transition has been added correctly by saving the modified fsa to a file, and checking that the new transition is in the file.
Exercise 23 Delete states
This exercise is optional for Honours students, and will award Bonus marks if completed.
Add a menu item delete that deletes the selected states from the fsa. To use this operation, a user selects one or more states on the fsa (by clicking on them, or by using the selection rectangle), and then chooses the delete option from the menu. The program now deletes these items from the fsa. Depending on how thoroughly you have tested previously, you may need to modify the code that implements placesChanged and transitionsChanged so that it correctly handles the removal of a state or a transition. When you have done this correctly, you should find that the rest of your program will correctly handle the changes to the display. You can verify that deletion is working by saving the modified fsa to a file, and checking that the deleted items are no longer in the file.
Exercise 24 Simulation
This exercise is optional for Honours students, and will award Bonus marks if completed.
In the control-bar at the bottom of the main window, add two buttons, labelled Reset, and Step, a text-field named Event. Write code so that the reset button resets the simulation, and the step button passes whatever is in the Event text field to the Fsa step function. You will also need to display the result of the isRecognised function in the control-bar, so a user can tell whether a sequence of events was recognised by the machine.
If all your earlier code was written correctly, you should find that the black dots move around the diagram as you feed events to your Fsa. Neat!
3. Assessment
Since the program is controlled by a GUI, it cannot be tested automatically; We will test each GUI by hand after the submission deadline.
During testing, we will check for features in the order described in the steps above. Marks will be awarded for each feature that works correctly. To be considered a reasonable effort, your program must be able to do the operations down to and including Exercise 18.
4. Submitting your Work
file:///Users/lyt/Desktop/Assignment3.htm
8/9
2019/10/21 Assignment 3
Your work will be submitted via SVN to the Web Submission System for manual marking.
Adding your files to SVN
1. Create a repository for this assignment, and check out a working directory, ready for work (replacing aXXXXXXX with your username):
svn mkdir parents -m Setup assignment 2 https://version-control.adelaide.edu.au/svn/aXXXXXXX/2019/s
2/edc/assignment3
svn checkout https://version-control.adelaide.edu.au/svn/aXXXXXXX/2019/s2/edc/assignment3
1. Create your FsaEditor.java and any other files you need in the folder you checked out. 2. Add and commit your files.
Submitting on Web Submission
1. Next, go to the web submission system at:
https://cs.adelaide.edu.au/services/websubmission/index.php (https://cs.adelaide.edu.au/services/websubmission/index.php? sub_year=2019&sub_period=s2&sub_course=edc&sub_assign=assignment3) and select 2019 -> Semester 2 -> Event Driven Computing -> Assignment 3
2. Click Make Submission, then Search Log Up To Revision and select the revision of work youd like to submit.
Click Submit/Re-Submit Selected Revision then complete the declaration. Websub will check whether your code compiles.
Submission Deadline
We recommend that you aim to complete your assignment by Friday of Week 12, however to give you as much time as possible, we will allow you to submit any time up until 11:59pm Friday of SWOT Week (8th November).
As this assignment is manually marked, you may submit as many times as you like up to the deadline, however only your last submission before the deadline will be marked.
Submissions made after 11:59pm, Friday 8th of November 2019 will not be accepted and will result in a mark of 0
file:///Users/lyt/Desktop/Assignment3.htm
9/9
Reviews
There are no reviews yet.