首页 > > 详细

Event Driven Computing Assignment 3 - FSA Editor

 Assignment 3 15/10/19, 8)28 pm

https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 1 of 10
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 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.
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 2 of 10
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->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 FsaPanel , that extends JPanel and implements FsaListener , and add it to the
main JFrame of your FsaEditor . 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
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 3 of 10
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. Don’t
worry, that’s coming soon!
Do not proceed until you have verified all is well!
Exercise 7 — Creating the StateIcon
Build a new class named StateIcon that extends JComponent , and implements StateListener . This class
will be used to display a state on the screen. You will need to override the paintComponent method, to make
the StateIcon paint a coloured circle on the screen.
Exercise 8 — Testing the StateIcon
The easist way to test the StateIcon , is to temporarily add some code to the constructor of the FsaPanel
class, so that it directly adds a StateIcon 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 statesChanged method in the FsaPanel so that each time it is called it calls the underlying
FsaImpl 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. (You’ll 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:
1. Creates a new StateIcon , and adds the StateIcon as a listener to p .
2. Arranges that the stateChanged method in the state icon sets the location of the StateIcon to the
coordinates of the state p , and then calls repaint.
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!)
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 4 of 10
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, isn’t 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!
Exercise 11 — Adding mouse actions
Modify the FsaPanel class so that it adds a MouseListener and a mouseMotionListener to the JComponent .
You will need to implement seven methods: mouseEntered , mouseExited mousePressed mouseClicked ,
mouseReleased , mouseMoved , and mouseDragged . Simply make each method-body print a trivial message that
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 doesn’t
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
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 5 of 10
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
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 don’t 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
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 6 of 10
(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, you’ll 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 won’t 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 icon’s isSelected flag to true. If the component doesn’t 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
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 JComponent , and implements TransitionListener .
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 7 of 10
This class will be used to display a transition on the screen. TransitionIcon and TransitionImpl 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 we've 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. Here’s a diagram that shows
the basic mathematics.
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 transitionsChanged() method adds a TransitionIcon to the FsaPanel
whenever a Transition is added to the underlying FsaImpl .
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!
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 8 of 10
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, there’s 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. (That’s 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
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.
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 9 of 10
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
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
Assignment 3 15/10/19, 8)28 pm
https://myuni.adelaide.edu.au/courses/45523/assignments/125878 Page 10 of 10
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 you'd 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
联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!