![]()
Step 3 - Navigation
This step makes the browser more useful by adding navigational aids for the user.
Adding Navigation Elements to the GUI
Add a location bar and navigation buttons to the BrowserFrame with the following code:
private Button backButton, forwardButton, reloadButton, stopButton; private Panel panel; private StormBase base; private String viewportId; private Label status; private TextField locationTextField;The following code is the final part of the constructor:
statusPanel.add(statusLabel); backButton = createButton("<<", font); backButton.setEnabled(false); forwardButton = createButton(">>", font); forwardButton.setEnabled(false); stopButton = createButton("stop", font); reloadButton = createButton("reload", font); Panel navigationPanel = new Panel(); gridBagLayout = new GridBagLayout(); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.fill = GridBagConstraints.NONE; navigationPanel.setLayout(gridBagLayout); gridBagLayout.setConstraints(backButton, gridBagConstraints); navigationPanel.add(backButton); gridBagLayout.setConstraints(forwardButton, gridBagConstraints); navigationPanel.add(forwardButton); gridBagLayout.setConstraints(stopButton, gridBagConstraints); navigationPanel.add(stopButton); gridBagLayout.setConstraints(reloadButton, gridBagConstraints); navigationPanel.add(reloadButton); locationTextField = new TextField(30); locationTextField.setFont(font); locationTextField.setBackground(Color.white); locationTextField.setForeground(Color.blue); locationTextField.addActionListener(this); gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; gridBagConstraints.gridwidth = GridBagConstraints.REMAINDER; gridBagConstraints.weightx = 1.0; gridBagLayout.setConstraints(locationTextField, gridBagConstraints); navigationPanel.add(locationTextField); controlPanel.add(navigationPanel, BorderLayout.NORTH); controlPanel.add(statusPanel, BorderLayout.SOUTH);The createButton( ) method is defined with this code:
private Button createButton(String label, Font font) { Button button = new Button(label); button.setFont(font); button.setBackground(Color.lightGray); button.addActionListener(this); return button; }Adding Navigation Functionality
Since the application has already registered with all the new widgets as java.awt.events.ActionListener, that interface needs to be implemented.
These lines ensure that the classes are imported:
import java.awt.event.*;The class definition is changed as follows:
class BrowserFrame extends Frame implements ActionListener, PropertyChangeListener {The interface defines one method, actionPerformed, which is called whenever one of the new widgets is activated:
public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if (source == backButton) { stormBase.getHistoryManager().goBack(viewportId); } else if (source == forwardButton) { stormBase.getHistoryManager().goForward(viewportId); } else if (source == stopButton) { stormBase.stopLoading(viewportId); } else if (source == reloadButton) { stormBase.getHistoryManager().reload(viewportId); } else if (source == locationTextField) { String location = locationTextField.getText(); if (location.startsWith("www.")) { location = "http://" + location; } stormBase.renderContent(location, null, viewportId); } }To handle navigation and histories of all the Viewports, the ice.storm.HistoryManager is used. It defines a public API that can be called from other classes as well as from StormBase. The code does the following:
- Location text field
When a user presses the Enter key when the location field has focus, the text in the field is retrieved and parsed, and the renderContent( ) method in StormBase is called. This causes the specified URL to be displayed in the window.- Reload button
If this button is pressed, the HistoryManager instance in the base is asked for the current location of the Viewport. If the location string is not null, the URL is rendered.- Back and forward buttons
A request to the HistoryManager is made so the user can go to the previous or next location.- Stop button
The StormBase.stopLoading( ) method is called.In addition, a few more property change events are taken into account. The new method is as follows:
public void propertyChange(PropertyChangeEvent event) { Viewport viewport = (Viewport)event.getSource(); String propertyName = event.getPropertyName(); String newValue; if (event.getNewValue() instanceof String) { newValue = (String)event.getNewValue(); } else { newValue = ""; } if (propertyName.equals(PropertyConstants.STATUS_LINE)) { statusLabel.setText(newValue); } else if (propertyName.equals(PropertyConstants.OUTSTANDING_IMAGES)) { if (!newValue.equals("0")) { statusLabel.setText("loading images: " + newValue + " left"); } else { statusLabel.setText("loading images: done"); } } else if (propertyName.equals(PropertyConstants.CONTENT_LOADING)) { if (newValue.equals(PropertyConstants.ERROR)) { ContentLoader contentLoader = (ContentLoader)event.getOldValue(); if (contentLoader != null) { statusLabel.setText( viewport.getName() + ": " + contentLoader.getException()); } else { statusLabel.setText(viewport.getName() + ": loading error"); } } else if (newValue.equals(PropertyConstants.BEGIN)) { backButton.setEnabled( stormBase.getHistoryManager().canGoBack(viewportId)); forwardButton.setEnabled( stormBase.getHistoryManager().canGoForward(viewportId)); } } else if ((propertyName.equals(PropertyConstants.LOCATION)) && (viewport.getId().equals(viewportId))) { locationTextField.setText(newValue); } else if ((propertyName.equals(PropertyConstants.TITLE)) && (viewport.getId().equals(viewportId))) { setTitle(" " + newValue); } }The check viewport.getId( ).equals(viewportID) is introduced to see if the Viewport is actually firing the events, and not one of its children. If it is, the title of the window is set upon receiving the title event. The text in the location field is set to the value of the location event. Last, the navigation buttons are enabled or disabled when the contentLoading,begin event is fired. When this happens, the HistoryManager has updated the history of the source of the event, and that is a good time to call the canGoBack/Forward( ) methods.
Now the browser has a more useful GUI and underlying functionality.
|
Copyright 2005. ICEsoft Technologies, Inc. http://www.icesoft.com |