Today, true believers, you'll get a chance to play with some Swing GUI controls. This lab is as much about events as it is about GUI controls (the two being closely tied) so you'll get a chance to learn more about event handling. Also, it is not possible to include all the GUI controls covered in Chapter 9, so I'm just having you work with a selected few. Your application project will give you the opportunity to experiment with many more GUI controls.
First of all, you will be starting with the Lab8_starter.java source code as a beginning point. You will be adding features to it until it looks like this.
Here's some detail of the "Load" menu:
Note that the menu entries correspond to the buttons.
Here's some more detail on how to add all of the above features.
Look at the JEditorPane docs for how to do this. (Scroll down just a little bit.) You can just cut-and-paste this code into the Lab8_starter class, such that it becomes an inner class.
Don't forget to call JEditorPane.addHyperlinkListener().
Firstly, think about the best data structure for keeping track of a list of visited URLs such that the last visited URL is the first one to be retrieved. Can you guess? You'll need to instantiate two of these: one for the "back list" (call it "backStack"), and one for the "forward list" (call it "forwardStack" or "fwdStack").
Nextly, You will need to make two more inner classes that implement the ActionListener interface, just like the LoadPage class. One of these will be called when you hit the "Back" button / menu (call it LoadPrev), the other will be called when you hit the "Forward" button / menu (call it LoadNext). Each of them will push / pop a string off of / on to the appropriate stack and call JEditorPane.setPage() to load the page. Make a new instance of each of LoadPrev and LoadNext in the same place where LoadPage is instantiated.
There are three different menu classes you will deal with here: JMenuItem, JMenu, and JMenuBar.
After you instantiate each new menu item, you should add an appropriate action listener by calling addActionListener() on each one.
This is a process very similar to the menus above. Simply make three instances of JButton classes and call JButton.addActionListener() adding the appropriate ActionListener derivative to each one.
For the button images, feel free to use these:
back.gif | forward.gif | reload.gif |
The best way to construct these is like so:
JButton backButton = new JButton(new ImageIcon("back.gif"));
You may want to make the following small edits to improve the app:
True. We are not using any extra threads in this app, so when the page loads, it ties up the single thread the app is running in. (Although I think the newer versions of the JDK (1.4.1) uses a seperate thread for the JEditorPane, so you might not experience as much of a "lockup", depending.)
These:
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.html.*; import java.util.Stack;
Incidentally, you can find out which packages you need to add by looking at the "Cannot resolve symbol" error messages, then looking up the class in the Java API Documentation on java.sun.com.
I ended up with five:
You should make a new, named instance of both LoadPrev and LoadNext and pass these instances to the addActionListener() methods of both the buttons and the menus.
Hats off to all the alert students who spotted this! The problem is caused by the way you put stuff on the forward/back stacks. The page that you are currently displaying is probably also on the top of the stack.
To cure this problem, use code like the following in your LoadPrev and LoadNext classes:
String prev; do { prev = (String)backStack.pop(); } while (prev.equals(textField.getText())); System.out.println("popped " + prev + " off the back stack");
That will make sure that you keep popping until you find the page before the one you're displaying now.
Strings. You can get the string to the current URL with HyperLinkEvent.getURL().toString(). Alternatively, if the text field is displaying the URL for the currently loaded page, you can type textField.getText()
Yep.
No. Please rename the class (and the file) to Lab8 (and Lab8.java).
So's your momma.
An excellent question. You can further develop your application project by plopping lots of GUI controls on your app, adding some Menus and maybe some Toolbars, possibly launching some Dialogs, and maybe using one of those funky Layout Managers.
Those of you that are making a web browser for your application project should find this lab useful. However, I would expect to see you add a few more features above and beyond the ones added in this lab.