完整的Java簡單瀏覽器


package book.net;
 
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
 
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.filechooser.FileFilter;
 
/**
  * 實現一個簡單的Web瀏覽器,支持HTML和HTM頁面的顯示。使用了JEditorPane組件
  **/
public class WebBrowser extends JFrame implements HyperlinkListener,
         PropertyChangeListener {
     
     /**下面是使用的Swing組件**/
     
     // 顯示HTML的面板
     JEditorPane textPane;
     // 最底下的狀態欄
     JLabel messageLine;
     // 網址URL輸入欄
     JTextField urlField;
     // 文件選擇器,打開本地文件時用
     JFileChooser fileChooser;
     
     // 后退和前進 按鈕
     JButton backButton;
     JButton forwardButton;
 
     // 保存歷史記錄的列表
     java.util.List history = new ArrayList();
     // 當前頁面的在歷史記錄列表中位置
     int currentHistoryPage = - 1
     // 當歷史記錄超過MAX_HISTORY時,清除舊的歷史
     public static final int MAX_HISTORY = 50 ;
 
     // 當前已經打開的瀏覽器窗口數
     static int numBrowserWindows = 0 ;
     // 標識當所有瀏覽器窗口都被關閉時,是否退出應用程序
     static boolean exitWhenLastWindowClosed = false ;
 
     // 默認的主頁
     String home = "http://www.google.com" ;
 
     /**
      * 構造函數
      */
     public WebBrowser() {
         super ( "WebBrowser" );
 
         // 新建顯示HTML的面板,並設置它不可編輯
         textPane = new JEditorPane();
         textPane.setEditable( false );
 
         // 注冊事件處理器,用於超連接事件。
         textPane.addHyperlinkListener( this );
         // 注冊事件處理器,用於處理屬性改變事件。當頁面加載結束時,觸發該事件
         textPane.addPropertyChangeListener( this );
 
         // 將HTML顯示面板放入主窗口,居中顯示
         this .getContentPane().add( new JScrollPane(textPane),
                                   BorderLayout.CENTER);
 
         // 創建狀態欄標簽,並放在主窗口底部
         messageLine = new JLabel( " " );
         this .getContentPane().add(messageLine, BorderLayout.SOUTH);
 
         // 初始化菜單和工具欄
         this .initMenu();
         this .initToolbar();
         
         // 將當前打開窗口數增加1
         WebBrowser.numBrowserWindows++;
         
         // 當關閉窗口時,調用close方法處理
         this .addWindowListener( new WindowAdapter() {
             public void windowClosing(WindowEvent e) {
                 close();
             }
         });
     }
     
     /**
      * 初始化菜單欄
      */
     private void initMenu(){
         
         // 文件菜單,下面有四個菜單項:新建、打開、關閉窗口、退出
         JMenu fileMenu = new JMenu( "文件" );
         fileMenu.setMnemonic( 'F' );
         JMenuItem newMenuItem = new JMenuItem( "新建" );
         newMenuItem.setMnemonic( 'N' );
         // 當“新建”時打開一個瀏覽器窗口
         newMenuItem.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 newBrowser();
             }
         });
         
         JMenuItem openMenuItem = new JMenuItem( "打開" );
         openMenuItem.setMnemonic( 'O' );
         // 當“打開”是打開文件選擇器,選擇待打開的文件
         openMenuItem.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 openLocalPage();
             }
         });
         
         JMenuItem closeMenuItem = new JMenuItem( "關閉窗口" );
         closeMenuItem.setMnemonic( 'C' );
         // 當“關閉窗口”時關閉當前窗口
         closeMenuItem.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 close();
             }
         });
         
         JMenuItem exitMenuItem = new JMenuItem( "退出" );
         exitMenuItem.setMnemonic( 'E' );
         // 當“退出”時退出應用程序
         exitMenuItem.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 exit();
             }
         });
         
         fileMenu.add(newMenuItem);
         fileMenu.add(openMenuItem);
         fileMenu.add(closeMenuItem);
         fileMenu.add(exitMenuItem);
         
         //幫助菜單,就一個菜單項:關於
         JMenu helpMenu = new JMenu( "幫助" );
         fileMenu.setMnemonic( 'H' );
         JMenuItem aboutMenuItem = new JMenuItem( "關於" );
         aboutMenuItem.setMnemonic( 'A' );
         helpMenu.add(aboutMenuItem);
         
         JMenuBar menuBar = new JMenuBar();
         menuBar.add(fileMenu);
         menuBar.add(helpMenu);
         
         // 設置菜單欄到主窗口
         this .setJMenuBar(menuBar);
     }
     
     /**
      * 初始化工具欄
      */
     private void initToolbar(){
         // 后退按鈕,退到前一頁面。初始情況下該按鈕不可用
         backButton = new JButton( "后退" );
         backButton.setEnabled( false );
         backButton.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 back();
             }
         });
         
         // 前進按鈕,進到前一頁面。初始情況下該按鈕不可用
         forwardButton = new JButton( "前進" );
         forwardButton.setEnabled( false );
         forwardButton.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 forward();
             }
         });
         
         // 前進按鈕,進到前一頁面。初始情況下該按鈕不可用
         JButton refreshButton = new JButton( "刷新" );
         refreshButton.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 reload();
             }
         });
         
         // 主頁按鈕,打開主頁
         JButton homeButton = new JButton( "主頁" );
         homeButton.addActionListener( new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 home();
             }
         });
         
         JToolBar toolbar = new JToolBar();
         toolbar.add(backButton);
         toolbar.add(forwardButton);
         toolbar.add(refreshButton);
         toolbar.add(homeButton);
 
         // 輸入網址的文本框
         urlField = new JTextField();
         // 當用戶輸入網址、按下回車鍵時,觸發該事件
         urlField.addActionListener( new ActionListener() {
                 public void actionPerformed(ActionEvent e) {
                     displayPage(urlField.getText());
                 }
             });
 
         // 地址標簽
         toolbar.add( new JLabel( "         地址:" ));
         toolbar.add(urlField);
 
         // 將工具欄放在主窗口的北部
         this .getContentPane().add(toolbar, BorderLayout.NORTH);
     }
 
     /**
      * 設置瀏覽器是否在所有窗口都關閉時退出
      * @param b
      */
     public static void setExitWhenLastWindowClosed( boolean b) {
         exitWhenLastWindowClosed = b;
     }
 
     /**
      * 設置主頁
      * @param home  新主頁
      */
     public void setHome(String home) {
         this .home = home;
     }
     /**
      * 獲取主頁
      */
     public String getHome() {
         return home;
     }
 
     /**
      * 訪問網址URL
      */
     private boolean visit(URL url) {
         try {
             String href = url.toString();
             // 啟動動畫,當網頁被加載完成時,觸發propertyChanged事件,動畫停止。
             startAnimation( "加載 " + href + "..." );
             
             // 設置顯示HTML面板的page屬性為待訪問的URL,
             // 在這個方法里,將打開URL,將URL的流顯示在textPane中。
             // 當完全打開后,該方法才結束。
             textPane.setPage(url);
             
             // 頁面打開后,將瀏覽器窗口的標題設為URL
             this .setTitle(href); 
             // 網址輸入框的內容也設置為URL
             urlField.setText(href);
             return true ;
         } catch (IOException ex) {
             // 停止動畫
             stopAnimation();
             // 狀態欄中顯示錯誤信息
             messageLine.setText( "不能打開頁面:" + ex.getMessage());
             return false ;
         }
     }
 
     /**
      * 瀏覽器打開URL指定的頁面,如果成功,將URL放入歷史列表中
      */
     public void displayPage(URL url) {
         // 嘗試訪問頁面
         if (visit(url)) {
             // 如果成功,則將URL放入歷史列表中。
             history.add(url);
             int numentries = history.size();
             if (numentries > MAX_HISTORY+ 10 ) {
                 history = history.subList(numentries-MAX_HISTORY, numentries);
                 numentries = MAX_HISTORY;
             }
             // 將當前頁面下標置為numentries-1
             currentHistoryPage = numentries - 1 ;
             // 如果當前頁面不是第一個頁面,則可以后退,允許點擊后退按鈕。
             if (currentHistoryPage > 0 ){
                 backButton.setEnabled( true );
             }
         }
     }
 
     /**
      * 瀏覽器打開字符串指定的頁面
      * @param href  網址
      */
     public void displayPage(String href) {
         try {
             // 默認為HTTP協議
             if (!href.startsWith( "http://" )){
                 href = "http://" + href;
             }
             displayPage( new URL(href));
         }
         catch (MalformedURLException ex) {
             messageLine.setText( "錯誤的網址: " + href);
         }
     }
 
     /**
      * 打開本地文件
      */
     public void openLocalPage() {
         // 使用“懶創建”模式,當需要時,才創建文件選擇器。
         if (fileChooser == null ) {
             fileChooser = new JFileChooser();
             // 使用文件過濾器限制只能夠HTML和HTM文件
             FileFilter filter = new FileFilter() {
                     public boolean accept(File f) {
                         String fn = f.getName();
                         if (fn.endsWith( ".html" ) || fn.endsWith( ".htm" )){
                             return true ;
                         } else {
                             return false ;
                         }
                     }
                     public String getDescription() {
                         return "HTML Files" ;
                     }
                 };
             fileChooser.setFileFilter(filter);
             // 只允許選擇HTML和HTM文件
             fileChooser.addChoosableFileFilter(filter);
         }
 
         // 打開文件選擇器
         int result = fileChooser.showOpenDialog( this );
         // 如果確定打開文件,則在當前窗口中打開選擇的文件
         if (result == JFileChooser.APPROVE_OPTION) {
             File selectedFile = fileChooser.getSelectedFile( );
             try {
                 displayPage(selectedFile.toURL());
             } catch (MalformedURLException e) {
                 e.printStackTrace();
             }
         }
     }
     /**
      * 后退,回到前一頁
      */
     public void back() {
         if (currentHistoryPage > 0 ){
             // 訪問前一頁
             visit((URL)history.get(--currentHistoryPage));
         }
         // 如果當前頁面下標大於0,允許后退
         backButton.setEnabled((currentHistoryPage > 0 ));
         // 如果當前頁面下標不是最后,允許前進
         forwardButton.setEnabled((currentHistoryPage < history.size()- 1 ));
     }
     /**
      * 前進,回到后一頁
      */
     public void forward() {
         if (currentHistoryPage < history.size( )- 1 ){
             visit((URL)history.get(++currentHistoryPage));
         }
         // 如果當前頁面下標大於0,允許后退
         backButton.setEnabled((currentHistoryPage > 0 ));
         // 如果當前頁面下標不是最后,允許前進
         forwardButton.setEnabled((currentHistoryPage < history.size()- 1 ));
     }
     /**
      * 重新加載當前頁面
      */
     public void reload() {
         if (currentHistoryPage != - 1 ) {
             // 先顯示為空白頁
             textPane.setDocument( new javax.swing.text.html.HTMLDocument());
             // 再訪問當前頁
             visit((URL)history.get(currentHistoryPage));
         }
     }
     /**
      * 顯示主頁
      */
     public void home() {
         displayPage(getHome());
     }
     /**
      * 打開新的瀏覽器窗口
      */
     public void newBrowser() {
         WebBrowser b = new WebBrowser();
         // 新窗口大小和當前窗口一樣大
         b.setSize( this .getWidth(), this .getHeight());
         b.setVisible( true );
     }
     /**
      * 關閉當前窗口,如果所有窗口都關閉,則根據exitWhenLastWindowClosed屬性,
      * 判斷是否退出應用程序
      */
     public void close() {
         // 先隱藏當前窗口,銷毀窗口中的組件。
         this .setVisible( false );
         this .dispose();
         // 將當前打開窗口數減1。
         // 如果所有窗口都已關閉,而且exitWhenLastWindowClosed為真,則退出
         // 這里采用了synchronized關鍵字,保證線程安全
         synchronized (WebBrowser. class ) {   
             WebBrowser.numBrowserWindows--;
             if ((numBrowserWindows== 0 ) && exitWhenLastWindowClosed){
                 System.exit( 0 );
             }
         }
     }
     /**
      * 退出應用程序
      */
     public void exit() {
         // 彈出對話框,請求確認,如果確認退出,則退出應用程序
         if ((JOptionPane.showConfirmDialog( this , "你確定退出Web瀏覽器?" , "退出" ,
                 JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)){
             System.exit( 0 );
         }
     }
     /**
      * 實現HyperlinkListener接口。處理超連接事件
      */
     public void hyperlinkUpdate(HyperlinkEvent e) {
         // 獲取事件類型
         HyperlinkEvent.EventType type = e.getEventType();
         // 如果是點擊了一個超連接,則顯示被點擊的連接
         if (type == HyperlinkEvent.EventType.ACTIVATED) {
             displayPage(e.getURL());
         }
         // 如果是鼠標移動到超連接上,則在狀態欄中顯示超連接的網址
         else if (type == HyperlinkEvent.EventType.ENTERED) {
             messageLine.setText(e.getURL().toString()); 
         }
         // 如果是鼠標離開了超連接,則狀態欄顯示為空
         else if (type == HyperlinkEvent.EventType.EXITED) {
             messageLine.setText( " " );
         }
     }
 
     /**
      * 實現PropertyChangeListener接口。處理屬性改變事件。
      * 顯示HTML面板textPane的屬性改變時,由該方法處理。
      * 當textPane調用完setPage方法時,page屬性便改變了。
      */
     public void propertyChange(PropertyChangeEvent e) {
         if (e.getPropertyName().equals( "page" )) {
             // 頁面加載完畢時,textPane的page屬性發生改變,此時停止動畫。
             stopAnimation();
         }
     }
 
     // 動畫消息,顯示在最底下狀態欄標簽上,用於反饋瀏覽器的狀態
     String animationMessage;
     // 動畫當前的幀的索引
     int animationFrame = 0 ;
     // 動畫所用到的幀,是一些字符。
     String[] animationFrames = new String[] {
         "-" , "\\" , "|" , "/" , "-" , "\\" , "|" , "/" ,
         "," , "." , "o" , "0" , "O" , "#" , "*" , "+"
     };
 
     /**
      * 新建一個Swing的定時器,每個125毫秒更新一次狀態欄標簽的文本
      */
     javax.swing.Timer animator =
         new javax.swing.Timer( 125 , new ActionListener() {
                 public void actionPerformed(ActionEvent e) {
                     animate();
                 }
             });
 
     /**
      * 顯示動畫的當前幀到狀態欄標簽上,並將幀索引后移
      */
     private void animate() {
         String frame = animationFrames[animationFrame++];
         messageLine.setText(animationMessage + " " + frame);
         animationFrame = animationFrame % animationFrames.length;
     }
 
     /**
      * 啟動動畫
      */
     private void startAnimation(String msg) {
         animationMessage = msg;
         animationFrame = 0 ;
         // 啟動定時器
         animator.start();
     }
 
     /**
      * 停止動畫
      */
     private void stopAnimation() { 
         // 停止定時器
         animator.stop();
         messageLine.setText( " " );
     }
     
     public static void main(String[] args) throws IOException {
         // 設置瀏覽器,當所有瀏覽器窗口都被關閉時,退出應用程序
         WebBrowser.setExitWhenLastWindowClosed( true );
         // 創建一個瀏覽器窗口
         WebBrowser browser = new WebBrowser();
         // 設置瀏覽器窗口的默認大小
         browser.setSize( 800 , 600 );
         // 顯示窗口
         browser.setVisible( true );
 
         // 打開主頁
         browser.displayPage(browser.getHome());
     }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM