// File: Browser4.java
// Tim Balls : Sept 1999
// Extends the scrolling Browser in Browser3.java
// to include a more complex model - one that
// can track a history of URLs
// Uses java.util.ArrayList to store the data
import javax.swing.*;
import javax.swing.event.*;
import java.net.*;
import java.io.IOException;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
public class Browser4 extends JFrame implements HyperlinkListener,
ActionListener
{ public static void main( String[] args )
{ if( args.length == 0 )
{ new Browser4( "NoURL" );
}
else
{ new Browser4( args[0] );
}
}
private JEditorPane html = new JEditorPane();
private JTextField location;
private JLabel statusLine = new JLabel( "", JLabel.LEFT );
private JButton back = new JButton( "<<" );
private JButton forward = new JButton( ">>" );
private HistoryList historyList = new HistoryList();
public Browser4( String site )
{ setSize( 550, 450 );
setTitle( "Simple Web Browser #4" );
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e )
{ System.exit( 0 );
}
});
// Build more interesting interface
location = new JTextField( site, 25 ); // 25 cols
JPanel topLine = new JPanel();
topLine.setLayout( new FlowLayout( FlowLayout.LEFT ) );
topLine.add( back );
topLine.add( forward );
topLine.add( new JLabel( "URL:" ) );
topLine.add( location );
location.addActionListener( this );
back.addActionListener( this );
forward.addActionListener( this );
// for the JFrame:
this.getContentPane().setLayout( new BorderLayout() );
this.getContentPane().add( topLine, BorderLayout.NORTH );
this.getContentPane().add( statusLine, BorderLayout.SOUTH );
if( !site.equals( "NoURL" ) )
{ loadURL( site );
}
JScrollPane scroller = new JScrollPane();
JViewport viewport = scroller.getViewport();
viewport.add( html );
this.getContentPane().add( scroller, BorderLayout.CENTER );
html.setEditable( false ); // to allow links to be activated
html.addHyperlinkListener( this );
setVisible( true );
}
// When a hyperlink is "clicked" :-
public void hyperlinkUpdate( HyperlinkEvent e )
{ if( e.getEventType() == HyperlinkEvent.EventType.ACTIVATED )
{ loadURL( e.getURL().toString() );
location.setText( "" + e.getURL() );
}
if( e.getEventType() == HyperlinkEvent.EventType.ENTERED )
{ statusLine.setText( "" + e.getURL() );
}
if( e.getEventType() == HyperlinkEvent.EventType.EXITED )
{ statusLine.setText( "" );
}
}
// When a new URL is entered (and return pressed)
public void actionPerformed( ActionEvent e )
{ // need to check which object called us
if( e.getSource() == location )
{ String site = location.getText();
loadURL( site );
}
if( e.getSource() == back )
{ historyList.back();
try
{
html.setPage( historyList.getCurrent() );
}
catch( IOException ioe )
{ System.out.println( "Can't load url: " + historyList.getCurrent() );
System.exit( 0 );
}
location.setText( historyList.getCurrent().toString() );
}
if( e.getSource() == forward )
{ historyList.forward();
try
{ html.setPage( historyList.getCurrent() );
}
catch( IOException ioe )
{ System.out.println( "Can't load url: " + historyList.getCurrent() );
System.exit( 0 );
}
location.setText( historyList.getCurrent().toString() );
}
}
// Attempt to load the html JEditorPane from the URL at "site"
private void loadURL( String site )
{ URL url = null;
try
{ url = new URL( site );
}
catch( MalformedURLException e )
{ System.out.println( "Invalid URL specified" );
System.exit( 0 );
}
try
{ html.setPage( url ); // load page
}
catch( IOException e )
{ System.out.println( "Can't load url: " + url );
System.exit( 0 );
}
// must be OK so add to history
historyList.add( url );
}
/* Encapsulate the behaviour of a history list for URLs
Enable/Disable the arrow controls so that
illegal operations are impossible
This class is (too) strongly coupled to its outer class
Maintain position in list, ensure that adding a new item
deletes any that would have followed (becomes new tail)
*/
private class HistoryList
{ private ArrayList history = new ArrayList();
private int current = 0;
public HistoryList()
{ back.setEnabled( false );
forward.setEnabled( false );
}
public void add( URL url )
{ if( history.size() > (current+1) )
{ history.subList( current+1, history.size() ).clear();
}
history.add( url );
current = history.size()-1;
if( current != 0 )
{ back.setEnabled( true );
}
forward.setEnabled( false );
}
/* Decrement the current pointer
PreCondition: must not be at start of list
*/
public void back()
{ current--;
if( current == 0 )
{ back.setEnabled( false );
}
if( current < (history.size()-1) )
{ forward.setEnabled( true );
}
}
/* Increment the current pointer
PreCondition: must not be at end of list
*/
public void forward()
{ current++;
if( current > 0 )
{ back.setEnabled( true );
}
if( current == (history.size()-1) )
{ forward.setEnabled( false );
}
}
/* Return the URL access by the current pointer
*/
public URL getCurrent()
{ return (URL)(history.get( current ));
}
}
}
|