目录
前言
这学期互联网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();
}
}