绘图

相关的类:

  • JFrame
  • JPanel

画到画板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Panel;

public class A
{
public static void main(String[] args) {
// 创建容器
JFrame frame = new JFrame();
frame.setSize(200, 300);
frame.setLocation(100, 100);
frame.setVisible(true);
// 创建画板
Panel panel = new Panel();
panel.setBackground(Color.YELLOW);
// 添加容器到画板
frame.add(panel);
}
}

画板子类

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
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Panel;
import java.util.Random;

public class M extends Panel {

int x[], y[];

public M() {
super();
// 初始化星星随机坐标
x = new int[300];
y = new int[300];
Random random = new Random();
for (int i = 0; i < 300; i++) {
x[i] = random.nextInt(1000);
y[i] = random.nextInt(600);
}
}

public void paint(Graphics g) {
super.paint(g);
this.setBackground(Color.black);
// 画月亮
g.setColor(Color.white);
g.fillArc(860, 100, 50, 50, 0, 360);
// 画星星(文字)
for (int i = 0; i < 300; i++) {
g.drawString("*", x[i], y[i]);
}
}
}

动态绘图

main

1
2
3
4
5
6
M panel = new M();
frame.add(panel);

Thread t = new Thread(panel);
panel.run(); // 开始多线程运行方法一
//t.start(); // 开始多线程运行方法二

M

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class M extends JPanel implements Runnable {

/* ... */

public void run() {
while (true) {
for (int i = 0; i < x.length; i++) {
x[i]--;
y[i]++;
}
try { // 定时(动态)操作
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 重绘函数
repaint();
}
}
}

解决闪烁

JPanel 自带双重缓冲。

动态绘图2

构造函数:

1
move(); // 直接调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void move() {
new Thread() {
public void run() {

/* ... 位置初始化 ... */

while (true) {

/* ... 控件移动 ... */

repaint();
try {
Thread.sleep(24);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

无边框

frame.setUndecorated(true);

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
BallPanel panel = new BallPanel();

frame.setBounds(100, 100, 1000, 600); // 代替setLocation和setSize
frame.setBackground(Color.YELLOW);
frame.setUndecorated(true);
frame.add(panel);
frame.setVisible(true);
}
}

实测setVisible必须在add和setUndecorated后面

设置图片

Graphics.drawImage()

1
2
3
4
5
public void paint(Graphics g) {
super.paint(g);

g.drawImage(new ImageIcon("img/pic.jpg").getImage(), 0, 0, this);
}

鼠标拖动

main 使用工具类

1
2
3
4
5
6
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
LocationUtil lUtil = new LocationUtil(frame); // 设置鼠标可拖动的工具类
}
}

util:LocationUtil 工具类

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
package Util;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

public class LocationUtil {
JFrame frame;
private int xx, yy;
private boolean isDraging = false;

public LocationUtil(JFrame f) {
this.frame = f;

// 鼠标按键事件
frame.addMouseListener(new MouseListener() {

public void mouseReleased(MouseEvent e) {
isDraging = false;
}

public void mousePressed(MouseEvent e) {
isDraging = true;
xx = e.getX();
yy = e.getY();
}

public void mouseExited(MouseEvent e) {

}

public void mouseEntered(MouseEvent e) {

}

public void mouseClicked(MouseEvent e) {

}
});

// 鼠标移动事件
frame.addMouseMotionListener(new MouseMotionListener() {

public void mouseMoved(MouseEvent e) {

}

public void mouseDragged(MouseEvent e) {
if (isDraging == true) {
int left = frame.getLocation().x;
int top = frame.getLocation().y;
frame.setLocation(left + e.getX() - xx, top + e.getY() - yy);
}
}
});
}
}

设置成屏幕大小

1
2
3
4
5
6
Dimension screensize = new Dimension();
screensize = tk.getScreenSize();
width = screensize.getWidth();
height = screensize.getHeight();
jframe.setSize((int)width, (int)height);
jframe.setLocation(0, 0);

java语法

单个变量形成数组

数组引用的是单个变量的地址空间,所以是同一个

1
2
3
4
5
6
Student s1 = new Student();
Student s2 = new Student();

Student[] ss = new Student[] { s1, s2 };

System.out.println(ss[1] == s2); // true

向上转型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void pout(Object o) {
System.out.println(o.toString());
}

public static void main(String[] args) {

Boolean b = new Boolean(false);
pout(b);

String s = new String("1431");
pout(s);

Integer i = new Integer(1000);
pout(i);
}

子类的创建、继承、覆盖

  • 构造函数只能调用,不能继承
  • 创建子类对象时在调用子类的构造器,会调用父类的(无参)构造器
  • 先对父类初始化,再对子类初始化
  • 子类构造器中使用super([参数])来调用父类的构造器
  • 如果父类只有有参构造器,则必须在子类构造函数第一行使用super([参数])来调用
  • 类、字段、构造器不存在覆盖的概念
  • 静态区优先于对象而创建,也不存在覆盖的概念(隐藏)。调用使用类名.方法,而非类示例.方法
  • 遮蔽 三种情况
    1. 局部变量和成员变量同名,使用this
    2. 子类和父类存在同名成员变量,使用super调用父类成员变量
    3. 子类和父类存在相同静态方法,方法不存在覆盖

多态

一个对象可以有多种形态
1. 父类指针指向子类对象
2. 把子类对象复制给父类的变量
3. 继承是多态的前提,没有继承就没有多态

多态的好处
- 把不同的子类对象都当做父类类型来看
- 可以屏蔽不同子类对象之间的差异

父类和子类同时存在静态方法时:
- 直接调用静态方法(子类)
- 父类名.静态方法
静态方法不是覆盖,而属于隐藏

多态是对象的概念,和类没有关系

instanceof 判断是否是某个(父)类的实例

1
if (a instanceof A) // true
1
2
3
B extends A;

if (b instanceof A) // true

(其实还有其他更深的用法,例如 c instanceof C 有 true 也有 false)

封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int i      = 129;

Integer I1 = new Integer(129);

Integer I2 = new Integer(129);

if (i == I1) // true

if (I1 == I2) // false

if (I1.equals(I2)) // true

Integer I3 = new Integer(127);

Integer I4 = new Integer(127)

if (I3 == I4) // true, 享元模式

当 < 128 时,Integer对象都是共享的;
当 >=128 时,才真正分配对象

就是用一个Integer数组先缓存了,后面如果是在 [-128, 127] 区间内的数直接从缓存数组中取,否则才构造新的Integer。
缓存思想还是很重要的。

控件常用函数

JFrame

1
2
3
4
5
6
setBounds(200, 50, 900, 700);
setUndecorated(true); // 无边框
setIconImage(new ImageIcon("").getImage());
add(panel);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel

1
setBackground(Color.black);

JButton

1
2
3
4
5
6
7
8
setBounds(100, 100, 200, 200);
addActionListener(click);
setActionCommand("close");
setBackground(Color.WHITE);
setOpaque(false); // 透明
setBorderPainted(false); // 无边框
setContentAreaFilled(false); // 按下透明
setIcon(new ImageIcon(""));

JLabel

1
2
3
4
5
6
setLayout(null);
setOpaque(false);
setBounds(19, 70, 235, 57);
setFont(new Font("宋体", Font.BOLD, 20));
setForeground(Color.white);
add(label2)