Cyh的博客

          Email:kissyan4916@163.com
          posts - 26, comments - 19, trackbacks - 0, articles - 220

          網絡編程>>Web瀏覽器

          Posted on 2009-12-12 15:17 啥都寫點 閱讀(470) 評論(0)  編輯  收藏 所屬分類: J2SE
               本例實現了一個Web瀏覽器,類似于Windows的Internet Explorer,但是功能相對簡單一些,能顯示HTML網頁、前進、后退、刷新、訪問主頁和新建窗口,當所有窗口關閉時,程序結束。

           javax.swing.JEditorPane文本控件支持純文本、HTML文本、RTF文本的顯示,可以用它來顯示HTML網頁。
           JEditorPane的setPage方法加載URL,當加載完畢后,觸發PropertyChangeListener事件,通過addPropertyChangeListener方法為JEditorPane注冊屬性改變事件處理器。
           為了使得網頁上的超鏈接生效,必須通過addHyperlinkListener為JEditorPane注冊超鏈接事件處理器。


          /**---------------------------------WebBrowser.java----------------------------------------*/

          package book.net.url;

          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;

          /**
           * 實現一個簡單的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(125new 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(800600);
                  
          // 顯示窗口
                  browser.setVisible(true); 

                  
          // 打開主頁
                  browser.displayPage(browser.getHome());
              }

          }



                                                                                                                 --    學海無涯
                  

          主站蜘蛛池模板: 广宁县| 子长县| 木兰县| 定结县| 巫山县| 广灵县| 秦皇岛市| 会宁县| 会同县| 叶城县| 宁明县| 舟曲县| 陵水| 南平市| 长沙县| 石景山区| 新建县| 江山市| 靖宇县| 武义县| 陵川县| 石景山区| 伊宁县| 麻栗坡县| 页游| 曲水县| 云和县| 临漳县| 华亭县| 巴青县| 都昌县| 迁西县| 措美县| 苏尼特左旗| 临朐县| 扎囊县| 甘谷县| 容城县| 洮南市| 宝应县| 遂宁市|