这部分是我阅读 《Head first Java》 的GUI部分笔记
个人认为GUI其实没有必要再学了
这部分学完,可以结合多线程等设计实现坦克大战,飞机大战等游戏了

绘图

java坐标系

左上角为坐标原点,以像素为单位.在java坐标系中,第一个是x坐标,表示当前位置的水平方向,距离坐标原点x个像素;第二个坐标是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素
原点为窗口的左上角,如果参数设置为负,图形可能无法完全显示出来
像素是一个密度单位,不是长度单位,两者无法比较

使用到的类

JFrame可以理解为一个窗口,一个画框/画板
JPanel可以理解为一支画板/画纸
Graphics g ,把 g 理解成一支画笔
总之,展示图形的类要继承JFrame

基本步骤:

  1. 需要先有一张画纸(继承JPanel),在画板上画图形
  2. 有了画板就要有一支画笔,就要重写JPanel的paint方法(调用父类构造器完成初始化)
  3. 让要展示图形的类继承JFrame,JFrame相当于一个画板/画框(画纸放在它上边)
  4. 在展示图形的类中先定义一张画纸,之后初始化这张画纸
  5. 初始化好画纸后将画纸放到会画板上,用从JFrame哪里继承来的add方法
  6. 设置窗口大小
  7. 最后在main中创建一个画图对象实例

绘图原理

  1. paint(Graphics g)绘制组件的外观
  2. repaint()刷新组件的外观

何时调用paint()

  1. 当组件第一次显示在屏幕上时会调用paint()
  2. 窗口最大化或最小化时调用paint()
  3. 拖动窗口,使得窗口大小发生变化时调用paint()
  4. repaint()方法会被调用

简单演示

先画一个圆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* @author 张永锐
* @aim 展示如何在面板上画一个圆
*/

import com.sun.javafx.logging.JFRInputEvent;

import javax.swing.*;
import java.awt.*;

/**
* 步骤:
* 1.需要先有一张画纸(继承JPanel),在画板上画图形
* 2.有了画板就要有一支画笔,就要重写JPanel的paint方法(调用父类构造器完成初始化)
* 3.让要展示图形的类继承JFrame,JFrame相当于一个画板/画框(画纸放在它上边)
* 4.在展示图形的类中先定义一张画纸,之后初始化这张画纸
* 5.初始化好画纸后将画纸放到会画板上,用从JFrame哪里继承来的add方法
* 6.设置窗口大小
* 7.最后在main中创建一个画图对象实例
*/
public class DrawCircle extends JFrame {//Frame的意思是框架
//定义一张画纸
private MyPanel mp =null;

public static void main(String[] args) {
new DrawCircle();//创建实例
}
//要展示团案的类的构造器
public DrawCircle() {
//初始化画纸
mp = new MyPanel();
//把画纸放到画板上
this.add(mp);
//设置窗口大小
this.setSize(800,500);
this.setVisible(true);//可以显示
}
}
//第一步,先弄一张画纸,方法是继承JPanel,JPanel会自动import javax.swing.*; 之后就直接在MyPanel上画
//第二步,弄一支画笔,重写paint方法,其中参数一定要,这个参数就是画笔,Graphics提供了很多画图方法
//第三步,让调用类继承一个JFrame,相当于一个画板
class MyPanel extends JPanel {
@Override
public void paint(Graphics g) {//绘图的方法
super.paint(g);//调用父类的方法,完成初始化 一定要有

//画圆,使用Graphics的drawOval()方法
//原型:public abstract void drawOval(int x,int y,int width,int height)
// 绘制椭圆的边框。得到一个圆或椭圆,它刚好能放入由 x、y、width 和 height 参数指定的矩形中。
//椭圆覆盖区域的宽度为 width + 1 像素,高度为 height + 1 像素。
//参数:
//x - 要绘制椭圆的左上角的 x 坐标。
//y - 要绘制椭圆的左上角的 y 坐标。
//width - 要绘制椭圆的宽度。
//height - 要绘制椭圆的高度。
//宽和高不相等就是椭圆,相等就是圆
g.drawOval(15,15,200,200);
}
}

画其他图形

解释都在注释中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import javax.swing.*;
import java.awt.*;
import java.util.Scanner;

/**
* @author 张永锐
* @aim 演示绘制其他常用图形
*/
@SuppressWarnings({"all"})
public class DrawOther extends JFrame {
private MyPanel2 mp2 = null;

public static void main(String[] args) {
input();
}

public static void input() {
DrawOther drawOther = new DrawOther();
System.out.println("+---选择要画的图形---+");
System.out.println(" 1.直线");
System.out.println(" 2.矩形");
System.out.println(" 3.填充矩形");
System.out.println(" 4.填充椭圆");
System.out.println(" 5.画图片");
System.out.println(" 6.画字符串");
System.out.println(" 0.退出");
System.out.println("+------------------+");
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
drawOther.Draw_(choice);
}

public void Draw_(int choice) {
switch (choice) {
case 1:
mp2 = new MyPanel2();//直线
this.add(mp2);
break;
case 2:
MyPanel3 mp3 = new MyPanel3();//画矩形(可以直接声明和初始化放到同一个语句执行)
this.add(mp3);
break;
case 3:
MyPanel4 mp4 = new MyPanel4();//画填充矩形
this.add(mp4);
break;
case 4:
MyPanel5 mp5 = new MyPanel5();
this.add(mp5);
break;
case 5:
MyPanel6 mp6 = new MyPanel6();
this.add(mp6);
break;
case 6:
MyPanel7 mp7 = new MyPanel7();
this.add(mp7);
break;
default:
System.out.println("输入错误");
return;
}
this.setSize(800, 500);
this.setVisible(true);
}
}

//画直线(演示了用三条直线围成的三角形)
class MyPanel2 extends JPanel {
@Override
public void paint(Graphics g) {
super.paint(g);
//演示画直线 用 drawLine(int x1,int y1,int x2,int y2)表示从起点(x1,y1)到终点(x2,y2)的直线
g.drawLine(25, 25, 90, 85);
g.drawLine(90, 85, 40, 92);
g.drawLine(40, 92, 25, 25);
}
}

//画矩形
class MyPanel3 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
//演示画矩形 用 drawRect(int x1,int y1,int x2,int y2)画一个以第一个坐标(x1,y1)与第二个左边(x2,y2)连成直线为对角线的矩形
graphics.drawRect(10, 10, 100, 100);
graphics.drawRect(45, 45, 145, 155);
}
}

//画填充矩形,要先设置填充颜色
class MyPanel4 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
//先用setColor来设置画笔颜色,颜色为:Color.颜色的英文
graphics.setColor(Color.blue);//例如设置为蓝色
//再填充矩形,用 fillRect(int x1,int y1,int x2,int y2)参数和drawRect()含义一样
graphics.fillRect(10, 10, 100, 100);
//再画一个用黄色填充的矩形,可以看出来,新的图形相当于是叠加再
graphics.setColor(Color.yellow);
graphics.fillRect(50, 50, 130, 150);
}
}

//画填充椭圆
class MyPanel5 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
//先设置画笔颜色
graphics.setColor(Color.black);
//再使用fillOval(),参数和drawOval()含义一样
graphics.fillOval(25, 25, 100, 160);
}
}

//画图片,这个比较复杂
//1.要获取图片资源
//2.将图片放到out.项目名下面(注意是项目名下面(这个文件是battle_city01))
//3.在函数中获取图片资源用getResource("/wb.png")表示在项目根目录下找名字为wb.png的图片资源
class MyPanel6 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
//得到图片,要用到Toolkit
Image image = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/wb.png"));
//画图片,前两个参数为图片在左上角的位置(x1,y1),后面两个数字为图片的长和宽,最好一样,最后一个参数为浏览位置,一般为this
graphics.drawImage(image,10,10,221,234,this);
}
}

//画字符串,实际上就是写字
class MyPanel7 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
//要先设置字体和颜色
graphics.setColor(Color.black);//设置字体颜色
graphics.setFont(new Font("行楷", Font.BOLD ,50));//设置字体,注意,setFont要求传入一个Font类型的对象
//画字符串,用函数drawString(String s,int x1,int y1),第一个参数为要写的字,后面两个参数是字符串左下角的坐标
graphics.drawString("冯雯",100,100);
graphics.setFont(new Font("隶书",Font.BOLD,50));//第一个参数为字体,第二个参数为形式,第三个参数为字体大小
graphics.drawString("张永锐",100,200);
}
}

关于颜色

得到随机颜色的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class RandomColor_ {
public static void main(String[] args) {
JFrame frame = new JFrame();
MyPanel1 mp1 = new MyPanel1();
frame.add(mp1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,800);
frame.setVisible(true);
}
}
class MyPanel1 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);

//这下面才是处理颜色的部分
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);

Color randomColor = new Color(red,green,blue);//传入3个参数来代表RGB值
graphics.setColor(randomColor);
graphics.fillOval(70,70,100,100);

red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
randomColor = new Color(red,green,blue);//传入3个参数来代表RGB值
graphics.setColor(randomColor);
graphics.fillOval(70,180,100,100);

red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
randomColor = new Color(red,green,blue);//传入3个参数来代表RGB值
graphics.setColor(randomColor);
graphics.fillOval(170,125,100,100);
}
}

渐变颜色

Gradient(意思是梯度,渐变)
使用类GradientPaint,表示渐变画嘛

1
2
3
4
Graphics2D g2d = (Graphics2D) graphics;
GradientPaint gradient = new GradientPaint(170,125,Color.blue,270,225,Color.orange);
g2d.setPaint(gradient);
graphics.fillOval(170,125,100,100);

与随机颜色结合(可执行程序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class RandomColor_ {
public static void main(String[] args) {
JFrame frame = new JFrame();
MyPanel1 mp1 = new MyPanel1();
frame.add(mp1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,800);
frame.setVisible(true);
}
}
class MyPanel1 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);

int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);

Color randomColor = new Color(red,green,blue);//传入3个参数来代表RGB值
graphics.setColor(randomColor);
graphics.fillOval(70,70,100,100);

red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
randomColor = new Color(red,green,blue);//传入3个参数来代表RGB值
graphics.setColor(randomColor);
graphics.fillOval(70,180,100,100);

//这里是使用随机改变渐变颜色
Graphics2D g2d = (Graphics2D) graphics;
GradientPaint gradient = new GradientPaint(170,125,randomColor,270,225,Color.orange);
g2d.setPaint(gradient);
graphics.fillOval(170,125,100,100);
}
}

得到一个按钮

使用按钮类JButton,注意,这里不是继承JFrame了,JFrame可以直接被使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class GUI_first {
public static void main(String[] args) {

JFrame frame = new JFrame();//一个画板
JButton button = new JButton("我是一个按钮,点击我");//一个按钮

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//在窗口关闭时把程序结束掉

frame.getContentPane().add(button);//把button加到frame的pane上

frame.setSize(300,300);//设置画板大小

frame.setVisible(true);//把frame显示出来
}
}

取得对象的事件

设置好了按钮就要对应按钮来执行事件,按钮按下后整么反应
接下来看文件取得用户的事件

不要再放在中间

frame.getContentPane().add(button);//把button加到
向上面直接使用add不给它更多的参数,会直接将画好的图形放在中间位置
其实add是可以有参数的
使用一个类BorderLayout(意思是边境布局(就表示布局嘛))

可选择的布局


根据英文其实已经能够看的懂了,也不多,合理选择即可
如下程序规定了图形放置添加位置:

规定位置的代码演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class GUI_third {
public static void main(String[] args) {
JFrame frame = new JFrame();
MyPanel2 myPanel2 = new MyPanel2();
JButton jButton = new JButton("Button1");
JButton button2 = new JButton("Button2");
JButton button3 = new JButton("Button3");
JButton button4 = new JButton("Button4");
frame.getContentPane().add(BorderLayout.CENTER,myPanel2);//将面板放在中间
frame.getContentPane().add(BorderLayout.AFTER_LAST_LINE,jButton);//放置一个按钮再下面
frame.getContentPane().add(BorderLayout.AFTER_LINE_ENDS,button2);//放置一个按钮再右边
frame.getContentPane().add(BorderLayout.BEFORE_LINE_BEGINS,button3);//放置一个按钮再左边
frame.getContentPane().add(BorderLayout.NORTH,button4);//放置一个按钮再上边
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
}
class MyPanel2 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
graphics.fillOval(0,0,100,100);
}
}

规定位置的代码演示的图形展示


注意,面板是在中间,只是圆形不在面板的中间而已,不是说面板不在中间

事件

接下来结合事件处理,做到点一下按钮将圆形的填充颜色换一下取得用户的事件

使用java.awt.event包中的事件对象,如:MouseEvent、KeyEvent、WindowEvent、ActionEvent等
每个事件类型都要有个接听窗口,例如想要接收MouseEvent就要实现MouseListener这个接口

取得按钮的ActionEvent

  1. 实现ActionEvent这个接口
  2. 像按钮注册(告诉按钮要监听的事件)
  3. 定义事件处理的方法(实现接口的方法)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import javax.swing.*;
import java.awt.event.*;

public class SimpleGui1B implements ActionListener {//实现此接口,表示发生事件会通知SimpleGui1B这个类(实现了的类)
JButton button;//声明一个按钮

public static void main(String[] args) {
SimpleGui1B gui = new SimpleGui1B();
gui.go();
}

public void go(){
JFrame frame = new JFrame();//创建并实例化一个画框
button = new JButton("click me");//实例化button

button.addActionListener(this);//向按钮注册

frame.getContentPane().add(button);//向窗口中添加这个按钮
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,300);定义窗口大小
frame.setVisible(true);//设置可视
}

//实现接口中的方法,这个方法才是真正处理事件的方法
//按钮以ActionEvent对象作为参数来调用此方法
public void actionPerformed(ActionEvent event){
button.setText("I've been clicked");
}
}

结合事件处理转换填充颜色

编写一个程序,有按钮和一个面板,面板随机产生不同颜色的填充圆,通过点击按钮可以切换圆的颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
* @author 张永锐
*/
public class GUI_fourth implements ActionListener {
JFrame frame;
public static void main(String[] args) {
new GUI_fourth().go();
}
public void go(){
frame = new JFrame();
JButton button1 = new JButton("Change Color");
button1.addActionListener(this);//为button1注册一个监听器

MyPanel3 myPanel3 = new MyPanel3();
frame.getContentPane().add(BorderLayout.CENTER,myPanel3);
frame.getContentPane().add(BorderLayout.SOUTH,button1);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event){
frame.repaint();//当用户按下按钮时就会要求重画(调用paint())
}
}
class MyPanel3 extends JPanel {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);

int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color color1 = new Color(red,green,blue);

red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color color2 = new Color(red,green,blue);

Graphics2D g2d = (Graphics2D) graphics;

GradientPaint gradientPaint = new GradientPaint(190, 180, color1, 300, 300, color2);
g2d.setPaint(gradientPaint);

g2d.fillOval(190,180,100,100);
}
}

实现两个按钮分别处理事件

通过内部类实现最好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
* @author 张永锐
*/
public class GUI_fifth {//这下不用主类来实现ActionListener接口了
//在外部定义,让实现ActionListener的实现类(这里就是内部类)能够用到
JFrame frame;
JLabel label;

public static void main(String[] args) {
new GUI_fifth().go();
}

public void go(){
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton label_button = new JButton("Change Label");//声明一个管理label的按钮
//原本使用this,相当于传入主类作为参数,只能使用主类的一个监听器,现在使用内部类传入实例作为,可以将不同的实例传入
label_button.addActionListener(new LabelListener());

JButton color_button = new JButton("Change Color");//声明一个管理color的按钮
color_button.addActionListener(new ColorListener());

label = new JLabel("I'm a label");
MyPanel4 myPanel4 = new MyPanel4();

frame.getContentPane().add(BorderLayout.WEST,label);
frame.getContentPane().add(BorderLayout.CENTER,myPanel4);
frame.getContentPane().add(BorderLayout.SOUTH,color_button);
frame.getContentPane().add(BorderLayout.EAST,label_button);

frame.setSize(500,500);
frame.setVisible(true);
}
//使用内部类分别单独实现ActionListener
class LabelListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
label.setText("Changed");
}
}
class ColorListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent event){
frame.repaint();
}
}
}
@SuppressWarnings({"all"})
class MyPanel4 extends JPanel {
@Override
public void paint(Graphics g){
g.setColor(Color.cyan);
g.fill3DRect(0,0,500,500,false);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color stare_color = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color end_color = new Color(red, green, blue);

Graphics2D g2d = (Graphics2D) g;

GradientPaint gradient = new GradientPaint(110,180,stare_color,210,180,end_color);
g2d.setPaint(gradient);

g2d.fillOval(110,180,100,100);
}
}

让图形动起来

通过点击按钮使得图形按固定方向移动

通过改变x和y(起始坐标)来每次重新画图,但是要注意抹去原本的痕迹
改变了x和y的值之后再直接调用继承了JPanel的类的方法:repaint()
下面的程序不仅实现了运动,还实现了事件处理(点一下按钮,动一下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
* @author 张永锐
*/
public class GUI_sixth {
int x = 70;
int y = 70;
MyDrawPanel drawPanel = new MyDrawPanel();

public static void main(String[] args) {
new GUI_sixth().go();
}

public void go() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton button = new JButton("Make the Circle Move");
button.addActionListener(new Color_Button());

frame.getContentPane().add(BorderLayout.CENTER,drawPanel);
frame.getContentPane().add(BorderLayout.SOUTH,button);

frame.setSize(500,500);
frame.setVisible(true);
}

class Color_Button implements ActionListener {
@Override
public void actionPerformed(ActionEvent actionEvent) {
for(int i = 0;i<3;i++) {
x++;
y++;

drawPanel.repaint();

try {
Thread.sleep(25);//使用线程的函数
} catch (Exception ex) {
}
}
}
}

class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fill3DRect(0,0,this.getWidth(),this.getHeight(),true);

int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color stare_color = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color end_color = new Color(red, green, blue);

Graphics2D g2d = (Graphics2D) g;

GradientPaint gradient = new GradientPaint(110,180,stare_color,210,180,end_color);
g2d.setPaint(gradient);

g2d.fillOval(x,y,50,50);
}
}
}

通过键盘控制移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

/**
* @author 张永锐
*/
public class GUI_seventh {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel myPanel = new MyPanel();
frame.getContentPane().add(BorderLayout.CENTER,myPanel);
frame.addKeyListener(myPanel);
frame.setSize(500,500);
frame.setVisible(true);
}
}

class MyPanel extends JPanel implements KeyListener {
int x = 10;
int y = 10;

@Override
public void paint(Graphics graphics) {
super.paint(graphics);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);//传入3个参数来代表RGB值
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
Graphics2D g2d = (Graphics2D) graphics;
GradientPaint gradient = new GradientPaint(0,0,startColor,500,500,endColor);
g2d.setPaint(gradient);
graphics.fillOval(x, y, 50, 50);
}

@Override
public void keyTyped(KeyEvent keyEvent) {

}

@Override
public void keyPressed(KeyEvent keyEvent) {
if (keyEvent.getKeyCode() == KeyEvent.VK_UP) {
y-=3;
this.repaint();
} else if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
y+=3;
this.repaint();
} else if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
x+=3;
this.repaint();
} else if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
x-=3;
this.repaint();
}
}

@Override
public void keyReleased(KeyEvent keyEvent) {

}
}