目錄
前言
這學期互聯網java課程的大作業下來了。。
挺難的但是害得做啊,要恰飯的嘛 我就是懶狗
老師說都是把學過的內容縫合一下,迫真作業擰螺絲期末造火箭Orz
關於服務器,之前已經實現過了:【Java用socket基於http協議搭建一個簡易的http服務器】
難點就是這個瀏覽器了。。。不過好在java有提供相關的輔助包,swing,那麼今天先來實現一個簡單的瀏覽器的基本功能
- 顯示html頁面
- 超鏈接跳轉
- 輸入URL並且跳轉到目標頁面
Swing及其組件介紹
什麼是swing
Swing是一個java的GUI工具包,這意味着它是java基礎類的一部分(強大的java救我狗命Orz),除此之外,Swing包括了圖形用戶界面(GUI)器件如:文本框,按鈕,分隔窗格和表。
JFrame
JFrame – java的GUI程序的基本思路是以JFrame爲基礎,它是屏幕上window的對象,能夠最大化、最小化、關閉。----菜鳥教程
JFrame是swing的基礎,也就是一個windows的窗口,可以縮放,關閉等功能。
使用以下幾行代碼可以快速創建一個空的JFrame窗口
import javax.swing.*;
JFrame jf = new JFrame("這是JFrame窗口");
jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jf.setSize(1200, 700);
jf.show();
使用add方法可以向JFrame窗口添加一些組件。這也是我們搭建簡易瀏覽器的基礎。
JPanel
JPanel – Java圖形用戶界面(GUI)工具包swing中的面板容器類,包含在javax.swing包中,可以進行嵌套,功能是對窗體中具有相同邏輯功能的組件進行組合,是一種輕量級容器,可以加入到JFrame窗體中。----菜鳥教程
簡單的來說,JPanel就像一種【盒子】,供我們添加元組件
你可能會問爲啥不直接向JFrame對象添加組件?
比如我希望JFrame中的組件縱向排列,而有一行組件需要橫向排列的時候,直接向JFrame添加就不能實現。
而我們實現一個橫向排列的JPanel,將所有橫向排列的組件裝起來,然後再在JFrame中縱向排列就可以實現。這只是其中的一個問題,而已,JPanel還有其他的用途,之後再談。
JTextField
JTextField –一個輕量級組件,它允許編輯單行文本。----菜鳥教程
就是一個輸入框,這個我們瀏覽器輸入URL會用到。
以下代碼可以簡單的生成一個輸入框。
import javax.swing.*;
JTextField jtf = new JTextField("這是輸入框");
JFrame jf = new JFrame("這是JFrame窗口");
jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jf.setSize(1200, 700);
jf.add(jtf);
jf.show();
JButton
JButton – JButton 類的實例。用於創建按鈕類似實例中的 “Login”。----菜鳥教程
一個按鈕組件,我們簡易瀏覽器也會用到。
JEditorPane
最最最重要的核心組件,JEditorPane類實現了對html的解析,並且以圖形化的形式渲染到窗口上。它可以直接處理html文檔,通過傳入一個簡單的URL字符串就可以自動打開網頁,相當方便了。
使用以下代碼來快速生成一個顯示頁面的demo,目標頁面是在我的個人服務器上部署的一個html測試頁面:http://www.szulrl.cn/browserTest
import javax.swing.*;
JEditorPane jep = new JEditorPane();
jep.setEditable(false); // 如果不設置則無法和超鏈接交互
jep.setContentType("text/html;charset=utf-8"); // 設置編碼類型
jep.setPage("http://www.szulrl.cn/browserTest"); // 設置URL
JFrame jf = new JFrame("這是JFrame窗口");
jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jf.setSize(1200, 700);
jf.add(jep); // 爲窗口添加顯示html的組件JEditorPane對象
jf.show();
JScrollPane
JScrollPane類可提供輕量級組件的 scrollable 視圖。JScrollPane 管理視口、可選的垂直和水平滾動條以及可選的行和列標題視口。---- 百度百科
一句話:滑動的窗口,當頁面過大的時候,可以像正常瀏覽器一樣上下滑動,所以我們一般將 JEditorPane 放到 JScrollPane 中,以實現滑動瀏覽。
思路
簡單瞭解 並不,👴在網上查各種用法查半天才弄出來的 了swing的一些組件之後,我們可以嘗試搭建一個簡易的瀏覽器了。下面給出組件的嵌套框架圖。
先上效果圖
各部分實現
html頁面顯示
和上面演示的基本無異,區別就是要將 JEditorPane 添加到 JScrollPane 組件中
JEditorPane jep = new JEditorPane();
jep.setEditable(false);
// 設置主頁
jep.setContentType("text/html;charset=utf-8");
try {
jep.setPage("http://www.szulrl.cn/browserTest");
} catch (IOException e) {
jep.setText("<html>Error! Could not load page</html>");
}
// 帶滑動條的組件 用於存放顯示html的jep組件
JScrollPane scrollpane = new JScrollPane(jep);
JFrame jf = new JFrame("這是JFrame窗口");
jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jf.setSize(1200, 700);
jf.add(scrollpane);
jf.show();
注意此時是可滑動的
輸入框與按鈕
值得注意的是要在向JFrame 調用 add 方法添加組件時,加上佈局方式及方位的修飾(見下面代碼),否則無法正常顯示。
// html顯示組件
JEditorPane jep = new JEditorPane();
jep.setEditable(false);
// 設置主頁
jep.setContentType("text/html;charset=utf-8");
try {
jep.setPage("http://www.szulrl.cn/browserTest");
} catch (IOException e) {
jep.setText("<html>Error! Could not load page</html>");
}
// 帶滑動條的組件 用於存放顯示html的jep組件
JScrollPane scrollpane = new JScrollPane(jep);
// 輸入框 輸入URL
JTextField jtf = new JTextField(40);
jtf.setText("http://www.szulrl.cn/browserTest");
// 按鈕
JButton goBtn = new JButton("點我訪問網頁");
// 上方菜單盒子
JPanel menuBox = new JPanel();
menuBox.add(jtf);
menuBox.add(goBtn);
// 主窗口JFrame
JFrame jf = new JFrame("這是JFrame窗口");
jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jf.setSize(1200, 700);
jf.add(menuBox, BorderLayout.NORTH); // 必須設置方位爲North才能在上方顯示
jf.add(scrollpane, BorderLayout.CENTER); // 設置訪問爲center
jf.show();
現在我們有基本的形狀了,但是你會發現,不管點擊超鏈接還是按回車還是點按鈕,都無法跳轉,所以我們需要綁定事件。這在接下來會講
綁定事件
注意需要一些event對象的import,詳情見【完整代碼】部分的import
綁定超鏈接事件
在剛剛的代碼上,加上如下代碼即可,值得注意的是,需要將JEditorPane對象改爲用final
修飾
final JEditorPane jep = new JEditorPane();
// 添加超鏈接點擊事件回調函數 並將JEditorPane的頁面改爲超鏈接的頁面
jep.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent event) {
if(event.getEventType()==HyperlinkEvent.EventType.ACTIVATED) {
try {
jep.setPage(event.getURL());
} catch (IOException e) {
jep.setText("<html>Error! Could not load page</html>");
}
}
}
});
綁定按鈕事件
在上文的代碼中添加如下代碼即可。
值得注意的是,因爲要獲取JTextField文本框的內容,需要用final
修飾JTextField對象
final JTextField jtf = new JTextField(40);
// 綁定訪問按鈕點擊事件 從JTextField輸入框獲取URL並且訪問
goBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
jep.setPage(jtf.getText());
} catch (IOException e1) {
jep.setText("<html>Error! Could not load page</html>");
}
}
});
綁定輸入框回車事件
在上文的代碼中添加如下代碼即可。
這裏直接調用按鈕的事件,即按回車訪問和按按鈕訪問是一個意思。因爲要用到按鈕對象JButton,同樣要用final修飾
final JButton goBtn = new JButton("點我訪問網頁");
// 綁定輸入框回車按鍵事件
jtf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent event) {
if(event.getKeyChar()==KeyEvent.VK_ENTER) {
goBtn.doClick(); // 按下回車等於點擊按鈕
}
}
});
完整代碼
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.*;
public class test {
public static void main(String[] args) throws Exception {
// html顯示組件
final JEditorPane jep = new JEditorPane();
jep.setEditable(false);
// 設置主頁
jep.setContentType("text/html;charset=utf-8");
try {
jep.setPage("http://www.szulrl.cn/browserTest");
} catch (IOException e) {
jep.setText("<html>Error! Could not load page</html>");
}
// 帶滑動條的組件 用於存放顯示html的jep組件
JScrollPane scrollpane = new JScrollPane(jep);
// 輸入框 輸入URL
final JTextField jtf = new JTextField(40);
jtf.setText("http://www.szulrl.cn/browserTest");
// 按鈕
final JButton goBtn = new JButton("點我訪問網頁");
// 上方菜單盒子
JPanel menuBox = new JPanel();
menuBox.add(jtf);
menuBox.add(goBtn);
// 添加超鏈接點擊事件回調函數 並將JEditorPane的頁面改爲超鏈接的頁面
jep.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent event) {
if(event.getEventType()==HyperlinkEvent.EventType.ACTIVATED) {
try {
jep.setPage(event.getURL());
} catch (IOException e) {
jep.setText("<html>Error! Could not load page</html>");
}
}
}
});
// 綁定訪問按鈕點擊事件 從JTextField輸入框獲取URL並且訪問
goBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
jep.setPage(jtf.getText());
} catch (IOException e1) {
jep.setText("<html>Error! Could not load page</html>");
}
}
});
// 綁定輸入框回車按鍵事件
jtf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent event) {
if(event.getKeyChar()==KeyEvent.VK_ENTER) {
goBtn.doClick(); // 按下回車等於點擊按鈕
}
}
});
JFrame jf = new JFrame("369危險瀏覽器");
jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jf.setSize(1200, 700);
jf.add(menuBox, BorderLayout.NORTH); // 必須設置方位爲North才能在上方顯示
jf.add(scrollpane, BorderLayout.CENTER); // 設置訪問爲center
jf.show();
}
}