Java之GUI编程(No.19)
GUI(Graphical User Interface,图形用户界面),是指采用图形方式显示的计算机操作用户界面。
GUI的核心技术:“AWT"与"Swing”。
- GUI缺点
- 1、界面不美观。
- 2、依赖JRE环境。
- 学习GUI目的
- 1、可以写出自定义的一些小工具。
- 2、可能会维护Swing界面(极小概率)。
- 3、了解MVC架构,了解监听。
1、AWT(Abstract Window Toolkit,抽象窗口工具包)
1.1、组件和容器(Component And Container)
1.1.1、示意图
1.1.2、Frame(框架窗口)
1.1.2.1、显示单个窗口(Show Single Window)
- 1.1.2.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui;
import java.awt.*;
/**
* GUI(图像用户界面)窗口:显示单个Frame窗口
*/
public class ShowSingleFrameWindow {
public static void main(String[] args) {
//创建Frame窗口
Frame frame=new Frame("显示单个Frame窗口");
//设置窗口可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(300,300);
//设置背景颜色
frame.setBackground(new Color(33, 65, 130));
//弹出的初始位置
frame.setLocation(150,150);
//设置窗体大小的固定性
frame.setResizable(false);
}
}
- 1.1.2.1.2、运行结果(Run Result)
其运行结果,如下图所示。
1.1.2.2、显示多个窗口(Show Multiple Window)
- 1.1.2.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui;
import java.awt.*;
/**
* GUI(图像用户界面)窗口:显示多个Frame窗口
*/
public class ShowMultipleFrameWindow {
public static void main(String[] args) {
//创建Frame窗口
new InheritFrame(300,200,300,200,Color.red);
new InheritFrame(600,200,300,200,Color.green);
new InheritFrame(300,400,300,200,Color.blue);
new InheritFrame(600,400,300,200,Color.yellow);
}
}
//自定义继承Frame类的InheritFrame类
class InheritFrame extends Frame{
static int frameID=0;//Frame窗口ID
public InheritFrame(int x,int y,int width,int height,Color color){
super("Frame窗口"+(++frameID));//使用父类构造方法设置窗口标题名称
this.setBackground(color);//设置窗口背景颜色
this.setBounds(x,y,width,height);//设置窗口初始位置以及大小
this.setVisible(true);//设置窗口可见性
}
}
- 1.1.2.2.2、运行结果(Run Result)
其运行结果,如下图所示。
1.1.3、Panel(面板)
使用Panel(面板)时,其无法单独显示,必须添加到某个容器中。
- 1.1.3.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.componentandcontainer.panel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* Panel(面板):无法单独显示,必须添加到某个容器中。
*/
public class ShowPanel {
public static void main(String[] args) {
//创建窗口
Frame frame = new Frame("添加Panel(面板容器)至Frame(窗口容器)中显示");
//创建面板
Panel panel=new Panel();
//设置窗口布局
frame.setLayout(null);//默认流式布局
//设置窗口坐标与宽高
frame.setBounds(200,200,400,400);
//设置窗口背景颜色
frame.setBackground(new Color(134, 37, 59));
//设置面板坐标与宽高
panel.setBounds(100,100,200,200);
//设置面板背景颜色
panel.setBackground(new Color(18, 82, 18));
//窗口添加面板,即,将面板添加窗口容器中显示
frame.add(panel);
//设置窗口可视性
frame.setVisible(true);
//设置窗口固定性
frame.setResizable(false);
//监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(new WindowAdapter())”
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时触发事件
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//结束程序
}
});
}
}
- 1.1.3.2、运行结果(Run Result)
其运行结果,如下图所示。
1.2、三种布局管理器(Three Layout Managers)
1.2.1、流程式布局(Flow Layout)
- 1.2.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.layout;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.UnsupportedEncodingException;
/**
* 流程式布局(即,流式布局)
*/
public class ShowFlowLayout {
public static void main(String[] args) throws UnsupportedEncodingException {
//创建窗口
Frame frame=new Frame("流程式布局(即,流式布局)");
//创建按钮
Button button1=new Button("button1");
Button button2=new Button("button2");
Button button3=new Button("button3");
Button button4=new Button("button4");
Button button5=new Button("button5");
Button button6=new Button("button6");
//设置窗口布局为“流程式布局”
frame.setLayout(new FlowLayout());
//设置窗口坐标与宽高
frame.setBounds(100,100,300,300);
//窗口添加按钮,即,将按钮添加窗口容器中显示
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
//设置窗口可视性
frame.setVisible(true);
//设置窗口固定性
frame.setResizable(false);
//监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时触发事件
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//结束程序
}
});
}
}
- 1.2.1.2、运行结果(Run Result)
其运行结果,如下图所示。
1.2.2、边框式布局(Border Layout)
- 1.2.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.layout;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 边框式布局
*/
public class ShowBorderLayout {
public static void main(String[] args) {
//创建窗口
Frame frame=new Frame("边框式布局");
//创建按钮
Button button1=new Button("button1");
Button button2=new Button("button2");
Button button3=new Button("button3");
Button button4=new Button("button4");
Button button5=new Button("button5");
//设置窗口布局为“边框式布局”
frame.setLayout(new BorderLayout());
//设置窗口坐标与宽高
frame.setBounds(100,100,300,300);
//窗口添加按钮,即,将按钮添加窗口容器中显示
frame.add(button1,BorderLayout.NORTH);
frame.add(button2,BorderLayout.WEST);
frame.add(button3,BorderLayout.CENTER);
frame.add(button4,BorderLayout.EAST);
frame.add(button5,BorderLayout.SOUTH);
//设置窗口可视性
frame.setVisible(true);
//设置窗口固定性
frame.setResizable(false);
//监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时触发事件
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//结束程序
}
});
}
}
- 1.2.2.2、运行结果(Run Result)
其运行结果,如下图所示。
1.2.3、网格式布局(Grid Layout)
- 1.2.3.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.layout;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 网格式布局
*/
public class ShowGridLayout {
public static void main(String[] args) {
//创建窗口
Frame frame=new Frame("网格式布局");
//创建按钮
Button button1=new Button("button1");
Button button2=new Button("button2");
Button button3=new Button("button3");
Button button4=new Button("button4");
//设置窗口布局为“边框式布局”
frame.setLayout(new GridLayout(2,2));
//窗口添加按钮,即,将按钮添加窗口容器中显示
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
// //使此窗口的大小适合其子组件的首选大小和布局
// frame.pack();
//设置窗口坐标与宽高
frame.setBounds(100,100,300,300);
//设置窗口可视性
frame.setVisible(true);
//设置窗口固定性
frame.setResizable(false);
//监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时触发事件
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//结束程序
}
});
}
}
- 1.2.3.2、运行结果(Run Result)
其运行结果,如下图所示。
1.3、练习:嵌套布局组件(Exercise:Nest Layout Component)
- 1.3.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.exercise;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 练习题:嵌套布局组件(如“Frame、Panel等”)
*/
public class NestLayoutComponent {
public static void main(String[] args) {
//创建窗口
Frame frame=new Frame("嵌套布局组件");
//设置窗口布局为“边框式布局”
frame.setLayout(new GridLayout(2,1));//网格式布局
//设置窗口坐标与宽高
frame.setBounds(200,200,400,400);
//设置窗口背景颜色
frame.setBackground(new Color(35, 139, 139));
//设置窗口可视性
frame.setVisible(true);
//设置窗口固定性
frame.setResizable(false);
//监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时触发事件
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//结束程序
}
});
//创建4个面板
Panel panel1=new Panel(new BorderLayout());//边框式布局
Panel panel2=new Panel(new GridLayout(2,1));//网格式布局
Panel panel3=new Panel(new BorderLayout());//边框式布局
Panel panel4=new Panel(new GridLayout(2,2));//网格式布局
//添加按钮至面板
panel1.add(new Button("WEST-1"),BorderLayout.WEST);
panel1.add(new Button("EAST-1"),BorderLayout.EAST);
for (int i = 0; i < 2; i++) {
panel2.add(new Button("CENTER-1-"+(i+1)));
}
panel1.add(panel2,BorderLayout.CENTER);
panel3.add(new Button("WEST-2"),BorderLayout.WEST);
panel3.add(new Button("EAST-2"),BorderLayout.EAST);
for (int i = 0; i < 4; i++) {
panel4.add(new Button("CENTER-2-"+(i+1)));
}
panel3.add(panel4,BorderLayout.CENTER);
//添加面板至窗口
frame.add(panel1);
frame.add(panel3);
}
}
- 1.3.2、运行结果(Run Result)
其运行结果,如下图所示。
1.4、按钮事件监听(Button Event Listener)
- 1.4.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.listenerevent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 事件监听:按钮事件监听
* 实现两个按钮“开始”与“停止”的同一个事件监听
*/
public class ButtonEventListener {
public static void main(String[] args) {
//创建窗口
Frame frame = new Frame("实现两个按钮“开始”与“结束”的同一个事件监听");
//创建按钮
Button button1 = new Button("Start");
Button button2 = new Button("Stop");
/**
* 事件监听:即,实现ActionListener接口类
* 可以显示定义触发会返回的命令,若不显示定义,则会返回默认值
* 多个按钮可以共用同一个监听类
*/
button2.setActionCommand("停止");//设置此按钮触发的操作事件的命令名称
//监听按钮事件
ImplementActionListener implementActionListener = new ImplementActionListener();
button1.addActionListener(implementActionListener);
button2.addActionListener(implementActionListener);
//设置窗口布局为“边框式布局”
frame.setLayout(new BorderLayout());
//设置窗口坐标与宽高
frame.setBounds(100, 100, 500, 500);
//窗口添加按钮,即,将按钮添加窗口容器中显示
frame.add(button1, BorderLayout.NORTH);
frame.add(button2, BorderLayout.SOUTH);
//设置窗口可视性
frame.setVisible(true);
// //设置窗口固定性
// frame.setResizable(false);
//关闭窗口
closeWindow(frame);
}
//关闭窗口
private static void closeWindow(Frame frame) {
//监听窗口关闭事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
}
//事件监听类
class ImplementActionListener implements ActionListener {
//重写ActionListener接口actionPerformed方法
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("当前点击了" + e.getActionCommand() + "按钮");
}
}
- 1.4.2、运行结果(Run Result)
其运行结果,如下图所示。
1.5、单行文本输入框事件监听(TextField Event Listener)
- 1.5.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.listenerevent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 事件监听:单行文本输入框事件监听
*/
public class TextFieldEventListener {
public static void main(String[] args) {
//创建启动类对象:一般建议使用此方式。
new StartUpFrame();
}
}
//启动类
class StartUpFrame extends Frame{
//无参构造方法
public StartUpFrame(){
//设置窗口标题名称
super("单行文本输入框事件监听");
//创建单行文本输入框
TextField textField = new TextField();
//添加单行文本输入框至窗口
add(textField);
//监听单行文本输入框事件:键盘按下Enter键时,就会触发单行文本输入框事件
textField.addActionListener(new ImplementTextFieldEventListener());
//设置替换编码字符
textField.setEchoChar('*');
//设置窗口坐标与宽高
setBounds(100, 100, 500, 500);
//设置窗口可视性
setVisible(true);
//关闭窗口
closeWindow(this);
}
//关闭窗口
private void closeWindow(Frame frame) {
//监听窗口关闭事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
}
//单行文本输入框事件监听类
class ImplementTextFieldEventListener implements ActionListener{
//重写ActionListener接口actionPerformed方法
@Override
public void actionPerformed(ActionEvent e) {
TextField textField= (TextField) e.getSource();//获取事件最初发生的对象
System.out.println(textField.getText());//获取单行文本输入框的输入文本信息
textField.setText("");//设置单行文本输入框的输入文本信息为空字符串,即,“清空单行文本输入框”
}
}
- 1.5.2、运行结果(Run Result)
其运行结果,如下图所示。
1.6、练习:简易计算器(Exercise:Simple Calculator)
1.6.1、使用普通类实现(Use Common Class Implementation)
其类似于面向过程的编程思想。
- 1.6.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.exercise.calculator;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 使用普通类实现简易计算器
*/
public class UseCommonClassImplementation {
public static void main(String[] args) {
new Calculator();//创建启动类对象
}
}
//计算器类
class Calculator extends Frame{
public Calculator(){
//设置窗口标题名称
super("使用普通类实现简易计算器");
//3个文本输入框
TextField textField1=new TextField(10);//被加数
TextField textField2=new TextField(10);//加数
TextField textField3=new TextField(20);//和
//1个按钮
Button button = new Button("=");//等号
//监听按钮事件
button.addActionListener(new CalculatorActionListener(textField1,textField2,textField3));
//1个标签
Label label = new Label("+");//加号
//设置窗口布局
setLayout(new FlowLayout());//流式布局
//添加组件
add(textField1);
add(label);
add(textField2);
add(button);
add(textField3);
//设置窗口组件自适应大小
pack();
//设置窗口可见性
setVisible(true);
//关闭窗口
closeWindow(this);
}
//关闭窗口
private void closeWindow(Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
}
//监听器类
class CalculatorActionListener implements ActionListener{
//属性
private TextField textField1,textField2,textField3;
public CalculatorActionListener(TextField textField1, TextField textField2, TextField textField3) {
this.textField1 = textField1;
this.textField2 = textField2;
this.textField3 = textField3;
}
@Override
public void actionPerformed(ActionEvent e) {
int add1=Integer.parseInt(textField1.getText());//被加数
int add2=Integer.parseInt(textField2.getText());//加数
textField3.setText(""+(add1+add2));//和
textField1.setText("");//清空被加数
textField2.setText("");//清空加数
}
}
- 1.6.1.2、运行结果(Run Result)
其运行结果,如下图所示。
1.6.2、使用组合类实现(Use Composite Class Implementation)
面向对象,且组合类要优于继承类。
- 1.6.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.exercise.calculator;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 使用组合类实现简易计算器
*/
public class UseCompositeClassImplementation {
public static void main(String[] args) {
new Calculator1();//创建启动类对象
}
}
//计算器类
class Calculator1 extends Frame {
//属性
TextField textField1,textField2,textField3;
//构造方法
public Calculator1(){
//设置窗口标题名称
super("使用组合类实现简易计算器");
startUpFrame();//调用启动方法
}
//启动方法
public void startUpFrame(){
//3个文本输入框
textField1=new TextField(10);//被加数
textField2=new TextField(10);//加数
textField3=new TextField(20);//和
//1个按钮
Button button = new Button("=");//等号
//监听按钮事件
button.addActionListener(new CalculatorActionListener1(this));
//1个标签
Label label = new Label("+");//加号
//设置窗口布局
setLayout(new FlowLayout());//流式布局
//添加组件
add(textField1);
add(label);
add(textField2);
add(button);
add(textField3);
//设置窗口组件自适应大小
pack();
//设置窗口可见性
setVisible(true);
//关闭窗口
closeWindow(this);
}
//关闭窗口
private void closeWindow(Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
}
//监听器类
class CalculatorActionListener1 implements ActionListener {
//组合类:即,在一个类中组合另一个类
Calculator1 calculator=null;
//构造方法
public CalculatorActionListener1(Calculator1 calculator) {
this.calculator = calculator;
}
//重写ActionListener接口actionPerformed方法
@Override
public void actionPerformed(ActionEvent e) {
int add1=Integer.parseInt(calculator.textField1.getText());//被加数
int add2=Integer.parseInt(calculator.textField2.getText());//加数
calculator.textField3.setText(""+(add1+add2));//和
calculator.textField1.setText("");//清空被加数
calculator.textField2.setText("");//清空加数
}
}
- 1.6.2.2、运行结果(Run Result)
其运行结果,如下图所示。
1.6.3、使用内部类实现(Use Internal Class Implementation)
面向对象,且内部类要优于组合类,其最大好处为“可以任意访问外部类的属性与方法”。
- 1.6.3.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.exercise.calculator;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 使用内部类实现简易计算器
*/
public class UseInternalClassImplementation {
public static void main(String[] args) {
new Calculator2();//创建启动类对象
}
}
//计算器类
class Calculator2 extends Frame {
//属性
TextField textField1,textField2,textField3;
//构造方法
public Calculator2(){
//设置窗口标题名称
super("使用内部类实现简易计算器");
startUpFrame();//调用启动方法
}
//启动方法
public void startUpFrame(){
//3个文本输入框
textField1=new TextField(10);//被加数
textField2=new TextField(10);//加数
textField3=new TextField(20);//和
//1个按钮
Button button = new Button("=");//等号
//监听按钮事件
button.addActionListener(new CalculatorActionListener2());
//1个标签
Label label = new Label("+");//加号
//设置窗口布局
setLayout(new FlowLayout());//流式布局
//添加组件
add(textField1);
add(label);
add(textField2);
add(button);
add(textField3);
//设置窗口组件自适应大小
pack();
//设置窗口可见性
setVisible(true);
//关闭窗口
closeWindow(this);
}
//关闭窗口
private void closeWindow(Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
//监听器类:即,内部类,可以更好的包装,其最大好处为“可以任意访问外部类的属性与方法”。
private class CalculatorActionListener2 implements ActionListener {
//重写ActionListener接口actionPerformed方法
@Override
public void actionPerformed(ActionEvent e) {
int add1=Integer.parseInt(textField1.getText());//被加数
int add2=Integer.parseInt(textField2.getText());//加数
textField3.setText(""+(add1+add2));//和
textField1.setText("");//清空被加数
textField2.setText("");//清空加数
}
}
}
- 1.6.3.2、运行结果(Run Result)
其运行结果,如下图所示。
1.7、画笔(Paint Brush)
- 1.7.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.componentandcontainer.frame;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 画笔
*/
public class PaintBrush {
public static void main(String[] args) {
new PaintClass();//创建启动类对象
}
}
//画笔类
class PaintClass extends Frame {
public PaintClass() {
super("画笔");
startUpFrame();
}
public void startUpFrame() {
setBounds(100, 100, 500, 500);
setVisible(true);
closeWindow(this);//关闭窗口
}
/**
* 重写Frame类paint方法
* 绘制组件:即,画笔.
*
* @param g
*/
@Override
public void paint(Graphics g) {
//画笔:需要有颜色,且可以绘画。
g.setColor(Color.BLUE);//蓝色颜色
g.draw3DRect(100, 100, 300, 300, true);//绘制一个3D的空心矩形
g.setColor(Color.GRAY);//灰色画笔
g.drawPolygon(new int[]{100, 250, 400,250}, new int[]{250, 100, 250,400}, 4);//绘制一个空心四边形(即,菱形)
g.setColor(Color.GREEN);//绿色画笔
g.drawOval(150, 150, 200, 200);//绘制一个空心园
g.setColor(Color.RED);//红色画笔
g.fillOval(200, 200, 100, 100);//绘制一个实心园
//画笔用完后,建议还原为最初的颜色。
g.setColor(Color.BLACK);//默认画笔颜色为黑色
}
//关闭窗口
private void closeWindow(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
}
- 1.7.2、运行结果(Run Result)
其运行结果,如下图所示。
1.8、鼠标事件监听(Mouse Event Listener)
模拟画图工具。
- 1.8.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.listenerevent;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 鼠标事件监听:模拟画图工具
* 1、使用画笔
* 2、监听鼠标当前位置坐标
* 3、使用集合列表存储所有的监听鼠标位置坐标
* 4、重新绘制组件
*/
public class MouseEventListener {
public static void main(String[] args) {
new PaintListenerMousePosition("模拟画图工具");//创建启动类对象
}
}
//画笔监听鼠标位置类
class PaintListenerMousePosition extends Frame{
//存储所有的监听鼠标位置坐标的集合列表
ArrayList mousePositionList;
public PaintListenerMousePosition(String title){
super(title);//设置窗口标题
mousePositionList=new ArrayList<>();
setBounds(100,100,500,500);//设置窗口位置与大小
setVisible(true);//设置窗口可见
this.addMouseListener(new MouseActionListener());//添加鼠标事件监听
closeWindow(this);//关闭窗口
}
//重写Frame类paint方法
@Override
public void paint(Graphics g) {
//画笔:即,绘制组件
Iterator iterator=mousePositionList.iterator();
while(iterator.hasNext()){
Point point= (Point) iterator.next();
g.setColor(Color.RED);
g.fillOval(point.x, point.y, 20,20);
}
}
//添加鼠标位置坐标至集合列表
public void addMousePositionList(Point point){
mousePositionList.add(point);
}
//适配器模式
private class MouseActionListener extends MouseAdapter{
//鼠标按下
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("当前鼠标按下");
}
//鼠标按下不放
@Override
public void mousePressed(MouseEvent e) {
System.out.println("当前鼠标按下不放");
PaintListenerMousePosition pLMP= (PaintListenerMousePosition) e.getSource();
pLMP.addMousePositionList(new Point(e.getX(),e.getY()));//添加当前鼠标坐标
pLMP.repaint();//重新绘制组件
}
//鼠标释放
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("当前鼠标释放");
}
}
//关闭窗口
private void closeWindow(Frame frame){
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
}
}
- 1.8.2、运行结果(Run Result)
其运行结果,如下图所示。
1.9、窗口事件监听(Window Event Listener)
分别使用内部类(Internal Class)与匿名内部类(Anonymous Internal Class)来实现,并且匿名内部类要比内部类更简洁方便”。
- 1.9.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.listenerevent;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 窗口事件监听:使用内部类或匿名内部类实现窗口事件监听,匿名内部类比内部类更简捷方便,一般建议使用匿名内部类。
* 局部内部类和匿名内部类最大的不同之处:局部内部类可以返回不止一个内部类的对象。
*/
public class WindowEventListener {
public static void main(String[] args) {
new WindowFrame1("使用内部类实现窗口事件监听");//创建启动类对象
new WindowFrame2("使用匿名内部类实现窗口事件监听");//创建启动类对象
}
}
//外部类
class WindowFrame1 extends Frame{
public WindowFrame1(String title){
super(title);//设置窗口标题
setBounds(100,100,400,300);//设置窗口坐标及大小
setVisible(true);//设置窗口可见
addWindowListener(new WindowActionListener());//添加窗口事件监听
}
//添加窗口事件监听:即,使用内部类实现
private class WindowActionListener extends WindowAdapter{
//窗口关闭事件
@Override
public void windowClosing(WindowEvent e) {
//setVisible(false);//设置窗口隐藏
System.exit(0);//关闭程序,正常退出
}
}
}
//外部类
class WindowFrame2 extends Frame{
public WindowFrame2(String title){
super(title);//设置窗口标题
setBounds(100,100,400,300);//设置窗口坐标及大小
setVisible(true);//设置窗口可见
//添加窗口事件监听:即,使用匿名内部类实现
addWindowListener(new WindowAdapter() {
//窗口关闭事件
@Override
public void windowClosing(WindowEvent e) {
//setVisible(false);//设置窗口隐藏
System.exit(0);//关闭程序,正常退出
}
//窗口激活事件
@Override
public void windowActivated(WindowEvent e) {
WindowFrame2 windowFrame2= (WindowFrame2) e.getSource();
windowFrame2.setTitle("使用匿名内部类实现窗口事件监听:窗口激活");
System.out.println("使用匿名内部类实现窗口事件监听:窗口激活");
}
});
}
}
- 1.9.2、运行结果(Run Result)
其运行结果,如下图所示。
1.10、键盘事件监听(Keyboard Event Listener)
- 1.10.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.listenerevent;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* 键盘事件监听
*/
public class KeyboardEventListener {
public static void main(String[] args) {
new KeyboardFrame("键盘事件监听");//创建启动类对象
}
}
//外部类
class KeyboardFrame extends Frame {
public KeyboardFrame(String title) {
super(title);
setBounds(100,100,300,300);
setVisible(true);
//添加窗口事件监听:即,使用匿名内部类实现
addWindowListener(new WindowAdapter() {
//窗口关闭事件
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//关闭程序
}
});
//添加键盘事件监听:即,使用匿名内部类实现
addKeyListener(new KeyAdapter() {
//键盘按下不放事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();//按键数值
int extendedKeyCode=e.getExtendedKeyCode();//按键扩展密钥代码
char keyChar=e.getKeyChar();//按键字符
int keyLocation=e.getKeyLocation();//按键位置
String keyText=KeyEvent.getKeyText(keyCode);//按键描述
System.out.println("按键字符("+keyChar+")按键数值("+keyCode+")按键位置("+keyLocation+")按键描述("+keyText+")按键扩展密钥代码("+extendedKeyCode+")");
}
});
}
}
- 1.10.2、运行结果(Run Result)
其运行结果,如下图所示。
2、Swing
Swing是一个用于开发Java应用程序用户界面的开发工具包。
Swing是以抽象窗口工具包(AWT)为基础 使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面。
2.1、JFrame窗口(JFrame Window)
- 2.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* JFrame窗口
*/
public class JFrameWindow {
public static void main(String[] args) {
new StartUpJFrame("JFrame窗口");//创建启动类对象
}
}
class StartUpJFrame extends JFrame{
public StartUpJFrame(String title){
super(title);//设置窗口标题
init();//调用启动方法
}
public void init(){
setBounds(100,100,300,300);//设置窗口坐标及大小
setVisible(true);//设置窗口可见
JLabel jLabel=new JLabel("JLabel标签");//新增标签
this.add(jLabel);//添加标签至窗口
jLabel.setHorizontalAlignment(SwingConstants.CENTER);//设置标签水平居中对齐
Container container=this.getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);获取此窗口容器的背景颜色
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
}
- 2.1.2、运行结果(Run Result)
其运行结果,如下图所示。
2.2、JDialog弹出窗口(JDialog Popup Window)
- 2.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* JDialog弹出窗口
*/
public class JDialogPopupWindow {
public static void main(String[] args) {
new MainWindow("JDialog主窗口");//创建启动类对象
}
}
//主窗口类
class MainWindow extends JFrame{
public MainWindow(String title){
super(title);//设置窗口标题
init();//调用启动方法
}
private void init(){
setBounds(100,100,300,300);//设置窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
Container container=this.getContentPane();//获取此窗口的容器
container.setLayout(null);//默认布局:即,绝对布局
container.setBackground(Color.RED);获取此窗口容器的背景颜色
JButton jButton=new JButton("弹出窗口按钮");//新增按钮
jButton.setBounds(50,50,150,100);//设置按钮坐标及大小
jButton.setHorizontalAlignment(SwingConstants.CENTER);//设置按钮水平居中对齐
//添加按钮事件监听
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new PopupDialog("JDialog弹出窗口");//弹出窗口
}
});
this.add(jButton);//添加按钮至窗口
}
}
//弹出窗口类
class PopupDialog extends JDialog{
public PopupDialog(String title){
setTitle(title);//设置弹出窗口标题
init();//调用启动方法
}
private void init(){
setBounds(400,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置弹出窗口可见
//setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭弹出窗口:无需设置此功能,否则异常
Container container=this.getContentPane();//获取此弹出窗口的容器
container.setLayout(null);//默认布局:即,绝对布局
container.setBackground(Color.GREEN);获取此弹出窗口容器的背景颜色
JLabel jLabel=new JLabel("JDialog弹出窗口的JLabel标签");//新增标签
jLabel.setBounds(50,50,200,100);//设置标签坐标及大小
jLabel.setHorizontalAlignment(SwingConstants.CENTER);//设置标签水平居中对齐
container.add(jLabel);//添加标签至容器
}
}
- 2.2.2、运行结果(Run Result)
其运行结果,如下图所示。
2.3、Icon与ImageIcon标签(Icon And ImageIcon Label)
2.3.1、Icon标签(Icon Label)
- 2.3.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* Icon:图标
* 1、继承JFrame类
* 2、实现Icon接口
* 特别注意:设置JFrame窗口为Container容器后,再设置JFrame窗口的参数(如坐标、大小、可见性等)才有效。
*/
public class IconLabel extends JFrame implements Icon {
private int width;//图标宽度
private int height;//图标高度
//无参构造方法
public IconLabel(){
}
//有参构造方法
public IconLabel(int width, int height){
super("Icon(图标)");
this.width = width;
this.height = height;
}
//主方法
public static void main(String[] args) {
new IconLabel(20,20).init();//调用启动方法
}
//启动方法
public void init(){
IconLabel iconLabel=new IconLabel(this.width,this.height);//设置图标宽高
//将图标放到标签上(也可以把图标放到按钮上)
JLabel jLabel=new JLabel("图标标签",iconLabel,SwingConstants.CENTER);
Container container=getContentPane();//获取此窗口的容器
//container.setLayout(null);//默认布局:即,绝对布局
container.setBackground(Color.RED);获取此窗口容器的背景颜色
container.add(jLabel);//添加标签至容器
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
System.out.println("图标名称""+getTitle()+"",图标宽度""+getIconWidth()+"",图标高度""+getIconHeight()+""");
}
//重写Icon接口的paintIcon方法
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.GREEN);//绿色画笔
g.fillOval(x,y,this.width,this.height);//填充绘制一个圆形图标
}
//重写Icon接口的getIconWidth方法
@Override
public int getIconWidth() {
return this.width;//返回图标宽度
}
//重写Icon接口的getIconHeight方法
@Override
public int getIconHeight() {
return this.height;//返回图标高度
}
}
- 2.3.1.2、运行结果(Run Result)
其运行结果,如下图所示。
2.3.2、ImageIcon标签(ImageIcon Label)
- 2.3.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* ImageIcon:图像图标
* 1、继承JFrame类
* 特别注意:设置JFrame窗口为Container容器后,再设置JFrame窗口的参数(如坐标、大小、可见性等)才有效。
*/
public class ImageIconLabel extends JFrame {
private int width;//图标宽度
private int height;//图标高度
//无参构造方法
public ImageIconLabel(){
super("ImageIcon(图像图标)");
}
//主方法
public static void main(String[] args) {
new ImageIconLabel().init();//调用启动方法
}
//启动方法
public void init(){
JLabel jLabel=new JLabel("图像图标标签");//新增标签
URL url=this.getClass().getResource("URLTest.jpg");//获取图像图标地址(URL)
ImageIcon imageIcon=new ImageIcon(url);//新增图像图标
jLabel.setIcon(imageIcon);//添加图像图标到标签
jLabel.setHorizontalAlignment(SwingConstants.CENTER);//设置标签水平居中对齐
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);获取此窗口容器的背景颜色
//container.setLayout(null);//默认布局:即,绝对布局
container.add(jLabel);//添加标签至容器
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
}
- 2.3.2.2、运行结果(Run Result)
其运行结果,如下图所示。
2.4、按钮与面板、文本域与滚动面板(Button And Panel,Text Area And Scroll Panel)
2.4.1、按钮与面板(Button And Panel)
- 2.4.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 按钮与面板
*/
public class ButtonAndPanel extends JFrame {
public ButtonAndPanel(){
super("按钮与面板");
init();
}
public void init(){
JPanel jPanel=new JPanel(new GridLayout(5,2,10,10));//新增面板,2行2列的网格布局,且上下左右间距为10
//新增按钮
jPanel.add(new JButton("按钮1"));
jPanel.add(new JButton("按钮2"));
jPanel.add(new JButton("按钮3"));
jPanel.add(new JButton("按钮4"));
jPanel.add(new JButton("按钮5"));
jPanel.add(new JButton("按钮6"));
jPanel.add(new JButton("按钮7"));
jPanel.add(new JButton("按钮8"));
jPanel.add(new JButton("按钮9"));
jPanel.add(new JButton("按钮10"));
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);获取此窗口容器的背景颜色
container.setLayout(new GridLayout(2,2,20,20));//新增容器,2行2列的网格布局,且上下左右间距为20
container.add(jPanel);//添加面板至容器
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new ButtonAndPanel();//创建启动类对象
}
}
- 2.4.1.2、运行结果(Run Result)
其运行结果,如下图所示。
2.4.2、文本域与滚动面板(Text Area And Scroll Panel)
- 2.4.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 文本域与滚动面板
*/
public class TextAreaAndScrollPanel extends JFrame {
public TextAreaAndScrollPanel(String title){
super(title);
init();
}
public void init(){
//新增文本域
JTextArea jTextArea=new JTextArea("文本域",30,30);
jTextArea.setText("文本域信息");//设置文本域信息
jTextArea.setToolTipText("文本域提示信息");//设置文本域提示信息
//新增滚动面板,且添加文本域到滚动面板
JScrollPane jScrollPane=new JScrollPane(jTextArea);
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);获取此窗口容器的背景颜色
container.add(jScrollPane);//添加滚动面板至容器
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new TextAreaAndScrollPanel("文本域与滚动面板");//创建启动类对象
}
}
- 2.4.2.2、运行结果(Run Result)
其运行结果,如下图所示。
2.5、图像按钮、单选框按钮、复选框按钮(Image Button,Radio Box Button,Check Box Button)
2.5.1、图像按钮(Image Button)
- 2.5.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
/**
* 图像按钮
*/
public class ImageButton extends JFrame{
public ImageButton(String title){
super(title);
init();
}
public void init(){
URL url=this.getClass().getResource("URLTest.jpg");//获取图像图标地址(URL)
Icon icon=new ImageIcon(url);//设置图像图标
JButton jButton=new JButton();//新增按钮
jButton.setIcon(icon);//添加图像图标到按钮
//jButton.setText("图像按钮");//设置按钮文本信息
jButton.setToolTipText("图像按钮");//设置按钮提示信息
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);获取此窗口容器的背景颜色
container.add(jButton);//添加按钮至容器
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new ImageButton("图像按钮");//创建启动类对象
}
}
- 2.5.1.2、运行结果(Run Result)
其运行结果,如下图所示。
2.5.2、单选框按钮(Radio Box Button)
- 2.5.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 单选框按钮
*/
public class RadioBoxButton extends JFrame{
public RadioBoxButton(String title){
super(title);
init();
}
public void init(){
//新增单选框按钮
JRadioButton jRadioButton1=new JRadioButton("单选框按钮1");
JRadioButton jRadioButton2=new JRadioButton("单选框按钮2");
JRadioButton jRadioButton3=new JRadioButton("单选框按钮3");
//新增按钮组
ButtonGroup buttonGroup=new ButtonGroup();
//添加单选框按钮至按钮组:确保一组单选框按钮每次只能选择一个单选框按钮
buttonGroup.add(jRadioButton1);
buttonGroup.add(jRadioButton2);
buttonGroup.add(jRadioButton3);
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//获取此窗口容器的背景颜色
container.setLayout(new FlowLayout(FlowLayout.CENTER));//获取此窗口容器的布局
//添加单选框按钮至容器
container.add(jRadioButton1);
container.add(jRadioButton2);
container.add(jRadioButton3);
setBounds(100,100,400,100);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new RadioBoxButton("单选框按钮");//创建启动类对象
}
}
- 2.5.2.2、运行结果(Run Result)
其运行结果,如下图所示。
2.5.3、复选框按钮(Check Box Button)
- 2.5.3.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 复选框按钮
*/
public class CheckBoxButton extends JFrame{
public CheckBoxButton(String title){
super(title);
init();
}
public void init(){
//新增复选框按钮
JCheckBox jCheckBox1=new JCheckBox("复选框按钮1");
JCheckBox jCheckBox2=new JCheckBox("复选框按钮2");
JCheckBox jCheckBox3=new JCheckBox("复选框按钮3");
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//获取此窗口容器的背景颜色
container.setLayout(new FlowLayout(FlowLayout.CENTER));//获取此窗口容器的布局
//添加复选框按钮至容器
container.add(jCheckBox1);
container.add(jCheckBox2);
container.add(jCheckBox3);
setBounds(100,100,400,100);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new CheckBoxButton("复选框按钮");//创建启动类对象
}
}
- 2.5.3.2、运行结果(Run Result)
其运行结果,如下图所示。
2.6、组合框、列表框(Combo Box,List Box)
2.6.1、组合框(Combo Box)
- 2.6.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 组合框
*/
public class ComboBoxContainer extends JFrame {
public ComboBoxContainer(String title){
super(title);
init();
}
public void init(){
//新增组合框
JComboBox jComboBox=new JComboBox();
jComboBox.addItem(null);
jComboBox.addItem("优秀");
jComboBox.addItem("良好");
jComboBox.addItem("及格");
jComboBox.addItem("不及格");
jComboBox.setBounds(50,50,200,100);//设置组合框坐标及大小
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//设置此窗口容器的背景颜色
container.setLayout(null);//设置此窗口容器的布局
//添加组合框至容器
container.add(jComboBox);
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new ComboBoxContainer("组合框");//创建启动类对象
}
}
- 2.6.1.2、运行结果(Run Result)
其运行结果,如下图所示。
2.6.2、列表框(List Box)
- 2.6.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
import java.util.Vector;
/**
* 下拉框
*/
public class ListBoxContainer extends JFrame {
public ListBoxContainer(String title){
super(title);
init();
}
public void init(){
//新增下拉框
JList jList1=new JList(new String[]{"","优秀","良好","及格","不及格"});
jList1.setBounds(30,50,100,100);//设置下拉框坐标及大小
Vector vector=new Vector();//可扩展的对象数组
JList jList2=new JList(vector);
jList2.setBounds(160,50,100,100);//设置下拉框坐标及大小
vector.add("");
vector.add("1");
vector.add("2");
vector.add("3");
vector.add("4");
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//设置此窗口容器的背景颜色
container.setLayout(null);//设置此窗口容器的布局
//添加下拉框至容器
container.add(jList1);
container.add(jList2);
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new ListBoxContainer("下拉框");//创建启动类对象
}
}
- 2.6.2.2、运行结果(Run Result)
其运行结果,如下图所示。
2.7、文本框、密码框、文本域(Text Field,Password Field,Text Area)
2.7.1、文本框(Text Field)
- 2.7.1.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 文本框
*/
public class TextFieldContainer extends JFrame {
public TextFieldContainer(String title){
super(title);
init();
}
public void init(){
//新增文本框
JTextField jTextField1=new JTextField("文本框1");
JTextField jTextField2=new JTextField("文本框2");
jTextField1.setBounds(30,50,100,100);//设置文本框坐标及大小
jTextField2.setBounds(150,50,100,100);//设置文本框坐标及大小
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//设置此窗口容器的背景颜色
container.setLayout(null);//设置此窗口容器的布局
//添加文本框至容器
container.add(jTextField1);
container.add(jTextField2);
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new TextFieldContainer("文本框");//创建启动类对象
}
}
- 2.7.1.2、运行结果(Run Result)
其运行结果,如下图所示。
2.7.2、密码框(Password Field)
- 2.7.2.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 密码框
*/
public class PasswordFieldContainer extends JFrame {
public PasswordFieldContainer(String title){
super(title);
init();
}
public void init(){
//新增密码框
JPasswordField jPasswordField=new JPasswordField();
jPasswordField.setEchoChar('*');//
jPasswordField.setBounds(30,50,100,100);//设置密码框坐标及大小
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//设置此窗口容器的背景颜色
container.setLayout(null);//设置此窗口容器的布局
//添加密码框至容器
container.add(jPasswordField);
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new PasswordFieldContainer("密码框");//创建启动类对象
}
}
- 2.7.2.2、运行结果(Run Result)
其运行结果,如下图所示。
2.7.3、文本域(Text Area)
- 2.7.3.1、示例代码(Sample Code)
其示例代码,如下所示。
package com.xueshanxuehai.gui.swing;
import javax.swing.*;
import java.awt.*;
/**
* 文本域
*/
public class TextAreaContainer extends JFrame{
public TextAreaContainer(String title){
super(title);
init();
}
public void init(){
//新增文本域
JTextArea jTextArea1=new JTextArea("文本域1",20,20);
JTextArea jTextArea2=new JTextArea("文本域2",20,20);
//新增滚动面板,且添加文本域到滚动面板
JScrollPane jScrollPane1=new JScrollPane(jTextArea1);
JScrollPane jScrollPane2=new JScrollPane(jTextArea2);
//设置滚动面板坐标及大小
jScrollPane1.setBounds(30,50,100,100);
jScrollPane2.setBounds(150,50,100,100);
Container container=getContentPane();//获取此窗口的容器
container.setBackground(Color.RED);//设置此窗口容器的背景颜色
container.setLayout(null);//设置此窗口容器的布局
//添加滚动面板至容器
container.add(jScrollPane1);
container.add(jScrollPane2);
setBounds(100,100,300,300);//设置弹出窗口坐标及大小
setVisible(true);//设置窗口可见
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
}
public static void main(String[] args) {
new TextAreaContainer("文本域");//创建启动类对象
}
}
- 2.7.3.2、运行结果(Run Result)
其运行结果,如下图所示。
3、练习:实现“贪吃蛇”游戏(Exercise:Realize The “Greedy Snake” Game)
3.1、游戏需求(Game Demand)
- 3.1.1、按空格键开始或暂停游戏。
- 3.1.2、按上、下、左、右键控制贪吃蛇的移动方向。
- 3.1.3、实时计算贪吃蛇的当前长度和当前积分。
3.2、示例代码(Sample Code)
- 3.2.1、游戏的启动类
GameStart类,其代码如下所示。
package com.xueshanxuehai.gui.swing.exercise.GreedySnake;
import javax.swing.*;
/**
* 游戏的启动类
*/
public class GameStart {
public static void main(String[] args) {
JFrame jFrame=new JFrame();//创建窗口对象
jFrame.setBounds(10,10,915,730);//设置窗口坐标及大小
jFrame.setResizable(false);//设置窗口固定
jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
jFrame.add(new GamePanel());//添加游戏面板至窗口
jFrame.setVisible(true);//设置窗口可见
}
}
- 3.2.2、游戏的面板类
GamePanel类,其代码如下所示。
package com.xueshanxuehai.gui.swing.exercise.GreedySnake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
/**
* 游戏的面板类
* 1、继承JPanel类
* 2、实现KeyListener接口
* 3、实现ActionListener接口
*/
public class GamePanel extends JPanel implements KeyListener, ActionListener {
//定义蛇的数据结构
int length;//蛇的长度
int[] snakeX = new int[600];//蛇的X坐标(25*25)
int[] snakeY = new int[600];//蛇的Y坐标(25*25)
String snakeDirection;//蛇的方向
boolean gameState = false;//游戏的状态(默认为停止)
Timer timer = new Timer(100, this);//定时器,每100毫秒执行一次,且被事件监听
int foodX;//食物的X坐标(25*25)
int foodY;//食物的Y坐标(25*25)
Random random=new Random();//随机数:随机食物的坐标基数
boolean gameIsFail=false;//游戏是否失败,默认为成功
int score;//成绩积分
//无参构造方法
public GamePanel() {
init();//调用初始化方法
setFocusable(true);//获得焦点
addKeyListener(this);//获得键盘监听事件
timer.start();//开启定时器,即”开始游戏“
}
//初始化方法
public void init() {
length = 3;//蛇的初始长度
snakeX[0] = 100;//蛇头的X坐标
snakeY[0] = 100;//蛇头的Y坐标
snakeX[1] = 75;//蛇身1的X坐标
snakeY[1] = 100;//蛇身1的Y坐标
snakeX[2] = 50;//蛇身2的X坐标
snakeY[2] = 100;//蛇身2的Y坐标
snakeDirection = "RIGHT";//蛇的初始方向,默认为蛇头向右
foodX=25+25*random.nextInt(((int)(850/25)-1));//随机食物的X坐标(25*25)
foodY=75+25*random.nextInt(((int)(600/25)-1));//随机食物的Y坐标(25*25)
score=0;//初始成绩积分
}
//绘制面板:游戏中的所有东西都由此方法此画笔来绘制
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);//清屏
//绘制静态的游戏面板
setBackground(Color.WHITE);//白色背景
GameResource.header.paintIcon(this, g, 25, 15);//绘制头部广告栏图片按钮
g.fillRect(25, 75, 850, 600);//绘制默认的矩形游戏界面
//绘制成绩积分
g.setColor(Color.GREEN);//绿色背景
g.setFont(new Font("宋体", Font.BOLD, 20));//设置字体
g.drawString("当前长度"+length, 750, 37);//绘制当前长度文本提示信息及大小
g.drawString("当前积分"+score, 750, 57);//绘制成绩积分文本提示信息及大小
//绘制食物
GameResource.food.paintIcon(this,g,foodX,foodY);//绘制食物
//绘制蛇头
if (snakeDirection.equals("RIGHT")) {
GameResource.right.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向右的蛇头
} else if (snakeDirection.equals("LEFT")) {
GameResource.left.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向左的蛇头
} else if (snakeDirection.equals("UP")) {
GameResource.up.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向上的蛇头
} else if (snakeDirection.equals("DOWN")) {
GameResource.down.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向下的蛇头
}
//绘制蛇身
for (int i = 1; i < length; i++) {
GameResource.body.paintIcon(this, g, snakeX[i], snakeY[i]);//绘制蛇身
}
//绘制游戏状态
if (!gameState) {
g.setColor(Color.WHITE);//白色背景
g.setFont(new Font("宋体", Font.BOLD, 30));//设置字体
g.drawString("请按下空格开始游戏", 200, 200);//绘制游戏状态文本提示信息及大小
}
//绘制游戏失败
if(gameIsFail){
g.setColor(Color.RED);//红色背景
g.setFont(new Font("宋体", Font.BOLD, 30));//设置字体
g.drawString("游戏失败,请按下空格重新开始游戏", 200, 200);//绘制游戏失败文本提示信息及大小
}
}
//键盘按下不放监听事件
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//获取按键值
if (keyCode == KeyEvent.VK_SPACE) {//按下空格键
if(gameIsFail){//游戏失败
gameIsFail=false;//重新开始游戏
init();//重新初始化
}else{
gameState = !gameState;//取反
}
repaint();//重绘
} else if (keyCode == KeyEvent.VK_RIGHT) {//按下向右键
snakeDirection = "RIGHT";
repaint();//重绘
} else if (keyCode == KeyEvent.VK_LEFT) {//按下向左键
snakeDirection = "LEFT";
repaint();//重绘
} else if (keyCode == KeyEvent.VK_UP) {//按下向上键
snakeDirection = "UP";
repaint();//重绘
} else if (keyCode == KeyEvent.VK_DOWN) {//按下向下键
snakeDirection = "DOWN";
repaint();//重绘
}
}
//事件监听:即,通过监听定时器事件来刷新
@Override
public void actionPerformed(ActionEvent e) {
if (gameState && !gameIsFail) {//若游戏为开始状态,且游戏未失败,则让蛇移动起来
//蛇吃食物
if(snakeX[0]==foodX && snakeY[0]==foodY){
length++;//蛇的长度加1
score+=10;//成绩积分加10
foodX=25+25*random.nextInt(((int)(850/25)-1));//随机食物的X坐标(25*25)
foodY=75+25*random.nextInt(((int)(600/25)-1));//随机食物的Y坐标(25*25)
}
//绘制移动蛇身坐标:后一个坐标移动到前一个坐标
for (int i = length - 1; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
if (snakeDirection.equals("RIGHT")) {
snakeX[0] += 25;//绘制移动蛇头坐标
if (snakeX[0] > 850) {
snakeX[0] = 25;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
}
} else if (snakeDirection.equals("LEFT")) {
snakeX[0] -= 25;//绘制移动蛇头坐标
if (snakeX[0] < 25) {
snakeX[0] = 850;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
}
} else if (snakeDirection.equals("UP")) {
snakeY[0] -= 25;//绘制移动蛇头坐标
if (snakeY[0] < 75) {
snakeY[0] = 650;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
}
} else if (snakeDirection.equals("DOWN")) {
snakeY[0] += 25;//绘制移动蛇头坐标
if (snakeY[0] > 650) {
snakeY[0] = 75;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
}
}
//游戏失败判定:即,撞到自身就算游戏失败
for (int i = 1; i < length; i++) {
if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
gameIsFail=true;//游戏失败
}
}
repaint();//重绘
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
- 3.2.3、游戏的资源类
GameResource类,其代码如下所示。
package com.xueshanxuehai.gui.swing.exercise.GreedySnake;
import javax.swing.*;
import java.net.URL;
/**
* 游戏的资源类
*/
public class GameResource {
public static URL headerURL=GameResource.class.getResource("images/header.png");//获取头部广告栏图片URL地址
public static ImageIcon header=new ImageIcon(headerURL);//新增头部广告栏图片按钮
public static URL upURL=GameResource.class.getResource("images/up.png");//获取蛇头向上图片URL地址
public static ImageIcon up=new ImageIcon(upURL);//新增蛇头向上图片按钮
public static URL downURL=GameResource.class.getResource("images/down.png");//获取蛇头向下图片URL地址
public static ImageIcon down=new ImageIcon(downURL);//新增蛇头向下图片按钮
public static URL leftURL=GameResource.class.getResource("images/left.png");//获取蛇头向左图片URL地址
public static ImageIcon left=new ImageIcon(leftURL);//新增蛇头向左图片按钮
public static URL rightURL=GameResource.class.getResource("images/right.png");//获取蛇头向右图片URL地址
public static ImageIcon right=new ImageIcon(rightURL);//新增蛇头向右图片按钮
public static URL bodyURL=GameResource.class.getResource("images/body.png");//获取蛇身体图片URL地址
public static ImageIcon body=new ImageIcon(bodyURL);//新增蛇身体图片按钮
public static URL foodURL=GameResource.class.getResource("images/food.png");//获取食物图片URL地址
public static ImageIcon food=new ImageIcon(foodURL);//新增食物图片按钮
}
3.3、运行结果(Run Result)
其运行结果,如下图所示。