JAVA的绘图功能

来源:互联网 发布:网络教育68所院校排名 编辑:程序博客网 时间:2024/05/22 03:43

JAVA的绘图功能

JAVA的绘图功能非常丰富,绘图包括字体、颜色、图形,以下我们将分技术专题来讲。
一、关于JAVA的绘图机制。
JAVA中的任何一个图形组件,小到文本框、标签,大到一个FRAME,一个DIALOG,都有一个专门负责显示其界面的函数,这个函数名称是固定的:paint,它的原型为:
public void paint(Graphics g)
{
……
}
每当组件大小、位置、组件内容发生变化时,该函数即负责生成新的图形界面显示。由于该函数可以被子类继承,因此,继承的子类有能力修改该函数。如果子类中没有出现该函数,则表示其行为完全继承自父类。则不管是组件中是否添加了新的内容,是否发生了大小的改变,是否发生了位移,父类都要有一个专门的线程,来负责描绘变化以后的组件界面。
下面就paint的运行机制给大家讲两个例子:
例子代码 在窗体上显示窗口的大小

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp1 extends JFrame
{
public GraExp1()
{
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
public void paint(Graphics g)
{
Dimension d=getSize();
int x=(int)d.getWidth();
int y=(int)d.getHeight();
g.clearRect(0,0,x,y);
String s=Integer.toString(x);
String s1=Integer.toString(y);
g.drawString(s,100,100);
g.drawString(","+s1,140,100);
}
public static void main(String[] args)
{
GraExp1 ge=new GraExp1();
}
}


程序分析:
(1)通过一次对比说明(把黑体字部分去掉,保留黑体字部分)默认的paint函数包含两部分:一是擦除,二是重画。
两次运行的图如下:








无黑体字部分的显示 有黑体字部分的显示

很明显可以看出,第一个图形是在原来画板的基础上进行了覆盖式描绘,第二个图形是擦除后的重新描绘。
(2)通过展示运行过程,可以看到,每次修改了窗体大小,都会自动调用paint函数一次。如果在实例化以后的界面中想重画,必须让代码出现在事件中。
(3)JAVA中的坐标轴:

例子二代码 在窗体中包含了添加的组件的paint示例

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp2 extends JFrame
{
Container c;
JTextField tf=new JTextField(10);
public GraExp2()
{
c=getContentPane();
c.setLayout(new FlowLayout());
tf.setText("世界,你好!");
c.add(tf);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
public void paint(Graphics g)
{
super.paint(g);
Dimension d=getSize();
int x=(int)d.getWidth();
int y=(int)d.getHeight();
g.clearRect(50,50,200,200);
String s=Integer.toString(x);
String s1=Integer.toString(y);
g.drawString(s,100,100);
g.drawString(","+s1,140,100);
}
 
public static void main(String[] args)
{
GraExp2 ge=new GraExp2();
}
}


程序分析:
(1)对比三种情况:无paint函数、有但无super.paint(g)调用、有paint函数并且也有对父类的paint函数调用,说明paint函数由父类自动维护,并且如果子类一旦重载该函数,必须自己去维护所有的界面显示。
后两者的运行图:


第二个图形中我故意让clearRect方法覆盖了文本框的一部分,其实其完整的操作画板的步骤是:首先清除窗体内容,并在窗体上真实再现文本框内容(注意,这一部分由父类完成),其次是调用clearRect方法,清除指定部分的窗体内容;最后是在合适的位置输出窗口大小。(这两部分是由子类完成的)。可以对比,在第一副图中,由于未调用父类的paint方法,所以添加到Frame中的文本框未被显示出来。

二、设置画笔颜色
1、颜色常识
任何颜色都是三原色组成(RGB),JAVA中支持224位彩色,即红绿蓝色分量可取值介于0..255之间。下面首先学习一个JAVA中的类Color
Color中的常量:
public final static Color black=new Color(0,0,0);
public final static Color blue=new Color(0,0,255);
…..
Color的构造函数:
public Color(int r,int g,int b);

使用举例:如果想构造一个灰色对象,则用下面的句子:
Color gray=new Color(205,205,205);

2、设置画笔颜色语法
g.setColor(color); //color是一个Color对象

举例三代码 演示颜色

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.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp3 extends JFrame
{
public GraExp3()
{
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
public void paint(Graphics g)
{
Dimension d=getSize();
int x=(int)d.getWidth();
int y=(int)d.getHeight();
Color color=Color.white;
g.setColor(color);
g.fillRect(0,0,x,y);
g.setColor(new Color(255,0,0));
g.drawString("红色是三原色中的首色,代表激情。",50,50);
g.setColor(new Color(0,255,0));
g.drawString("绿色是三原色中的次色,代表安逸。",50,80);
g.setColor(new Color(0,0,255));
g.drawString("蓝色是三原色中的末色,代表忧郁。",50,110);
}
 
public static void main(String[] args)
{
GraExp3 ge=new GraExp3();
}
}


程序运行图如下:

注意:每修改一次颜色它影响的就是下面所有的绘图语句,一直影响到再次碰到setColor函数才以新的颜色代替。

3、使用JColorChooser组件选择颜色
JAVA中有一个已经定义好的选色器,通过简单的语法我们就可以将该窗口调出来,从其中选择自己喜欢的颜色。下面的这个例子就是通过颜色选取器选取颜色,并将选择到的颜色做为窗体的背景色。
(1)JColorChooser简介
JColorChooser组件的showDialog()方法让用户从弹出的窗口中选择一个颜色,并传给Color对象。其调用语法如下:

color=JColorChooser.showDialog(this,”选色”,color);
第一个参数指定调用选色器的父窗体,第二个参数指定选色器窗口标题,最后一个为接收颜色的颜色对象。

(2)举例四代码: 更改窗体背景色

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.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp4 extends JFrame
{
Container c;
JButton btn=new JButton("选背景色");
Color color=new Color(200,200,200);
public GraExp4()
{
c=getContentPane();
c.setLayout(new FlowLayout());
c.add(btn);
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
color=JColorChooser.showDialog(null,"请选择你喜欢的颜色",color);
if (color==null) color=Color.lightGray;
c.setBackground(color);
c.repaint();
}
});
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
 
public static void main(String[] args)
{
GraExp4 ge=new GraExp4();
}
}


以下是程序运行单击按钮以后的JColorChooser图和更改后的窗体图:











程序注解:
其实这里并没有什么特殊的技巧,只是告诉你一个组件的简单用法。需要注意的是调用窗体后对返回的值必须进行检验,如果用户没有选择任何颜色,而是单击了撤消直接退出,程序员在自己的代码里必须为color指定一默认值,要不然在设置背景色时会产生错误。

4、如何将一个图形(以文件存在,如JPG或者GIF)画到窗体的画布中
其实放置图形到画板中实际就是调用了画板的drawImage函数。其大致思路如下:
首先获取一个ImageIcon对象,这个对象将会从指定的文件中读取相关图象信息,它支持GIF和JPG、BMP等基本图象格式。语法如下:
ImageIcon icon=new ImageIcon(GraExp5.class.getResource("1.gif"));
获取到图象的图标以后,就可以从图标中获取到绘制到画板上的实际需要的图象:
Image img=icon.getImage();
有了这个图象对象,我们就可以用画板的drawImage函数画图了。
g.drawImage(img,0,0,null);
中间两个参数是图象绘制时在画板的起始点坐标。
(1)举例五代码 将图形文件绘制到窗体中。

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp5 extends JFrame
{
ImageIcon icon;
Image img;
 
public GraExp5()
{
icon=new ImageIcon(GraExp5.class.getResource("1.gif"));
img=icon.getImage();
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
public void paint(Graphics g)
{
g.drawImage(img,0,0,null);
}
public static void main(String[] args)
{
GraExp5 ge=new GraExp5();
}
}



程序分析:
需要注意的是,图象文件所在的位置应该和该类放在同一个目录中,这样不至于出错。
程序的运行结果图如下:





6、系统扩展,综合应用,如何为一个窗体设置背景图片。
要为一个窗体添加背景图片,必须知道绘制JComponent组件的过程。Swing轻量组件的绘制是组件和组件UI代表合作的结果。
代码六 设置窗体背景图片

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp6 extends JFrame
{
CInstead c1=new CInstead();
Container c;
JLabel lbl1=new JLabel("姓名:");
JLabel lbl2=new JLabel("密码:");
JTextField tf1=new JTextField(10),
tf2=new JTextField(10);
 
public GraExp6()
{
setContentPane(c1);
c=getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));
c.add(lbl1);
c.add(tf1);
c.add(lbl2);
c.add(tf2);
 
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
public static void main(String[] args)
{
GraExp6 ge=new GraExp6();
}
class CInstead extends JPanel
{
ImageIcon icon;
Image img;
public CInstead()
{
icon=new ImageIcon(GraExp6.class.getResource("1.gif"));
img=icon.getImage();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(img,0,0,null);
}
}
}


界面运行图如下:

程序分析:
JComponent.paint先绘制组件,然后绘制组件的边框,再绘制组件的子组件。调用的顺序确保组件、边框和子组件都是可视的。如果组件有一个UI代表,则JComponent.paintComponent调用该代表的Update方法,该方法为不透明组件擦除背景,然后绘制组件。
CInstead是一个不透明的组件,如果重载paint方法,其背景图是无法被擦除的,因此,即使更新了组件的所有包含组件,在界面上是看不到的。所以必须重载paintComponent方法,在绘制子组件前先擦除背景。
对双缓存组件,paint方法负责把组件绘制到屏外缓存中,然后把屏外缓存拷贝到组件的屏上代表中,正因为如此,我们不建议为Swing组件重载paint,如果需要重新定义如何绘制组件,那么就重载paintComponent()。

7、用可获取的字体、样式、字号修饰文字
(1)函数说明:
字形类Font用于规范组件所使用的字形大小、样式和字体等。其构造函数:
public Font(String name,int style,int size);
name表示本地可获取字体名称
style表示字体样式,包含Font.PLAIN,Font.BOLD,Font.ITALIC三种,分别对应平体、加粗和斜体。

一个有用的方法用来获取本地可用字体
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fa=ge.getAvailableFontFamilyNames();
通过从绘图环境中获取到本地可用的字体名数组。
(2)代码七 用指定的字型约束来显示窗体上的字。

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
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
public class GraExp7 extends JFrame
{
CInstead c1=new CInstead();
Container c;
String[] zt;
String[] zx={"平体","加粗","斜体"};
 
String name="Serif";
int type=0;
int size=12;
JLabel lbl1=new JLabel("字体:");
JLabel lbl2=new JLabel("字形:");
JLabel lbl3=new JLabel("字号:");
 
JLabel lbl=new JLabel("测试用字abcABC123");
JComboBox cb1,
cb2=new JComboBox(zx);

JTextField tf1=new JTextField(25),
tf2=new JTextField(10);
 
public GraExp7()
{
//获取可用字体名称数组
GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment();
zt=ge.getAvailableFontFamilyNames();
cb1=new JComboBox(zt);
setContentPane(c1);
c=getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT));
c.add(lbl1);
c.add(cb1);
c.add(lbl2);
c.add(cb2);
c.add(lbl3);
c.add(tf1);
lbl.setPreferredSize(new Dimension(200,60));
lbl.setForeground(Color.red);
c.add(lbl);
 
cb1.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent event)
{
int state=event.getStateChange();
name=(String) event.getItem();
setCustomFont(name,type,size);
}
});
cb2.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent event)
{
int state=event.getStateChange();
String s=(String) event.getItem();
if (s.equals("平体")){
type=Font.PLAIN;
}else if(s.equals("加粗")){
type=Font.BOLD;
}else{
type=Font.ITALIC;
}

setCustomFont(name,type,size);
}
});
tf1.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
int c=e.getKeyCode();
if(c==10)
{
String s=tf1.getText();
size=Integer.parseInt(s);
setCustomFont(name,type,size);
}
}
});

setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(new Dimension(400,300));
show();
}
public static void main(String[] args)
{
GraExp7 ge=new GraExp7();
}
 
private void setCustomFont(String name,int type,int size)
{
lbl.setFont(new Font(name,type,size));
lbl.revalidate();
}
class CInstead extends JPanel
{
ImageIcon icon;
Image img;
public CInstead()
{
icon=new ImageIcon(CInstead.class.getResource("1.gif"));
img=icon.getImage();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(img,0,0,null);
}
}
}

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 塑料推拉门声音大怎么办不好推 推拉门锁扣坏了怎么办 衣柜移门拉不动怎么办?如何保养 擦黑色桌面有层白灰怎么办 宝宝睡觉不盖被子怎么办 孩子盖被子就哭怎么办 一盖被子就发烧怎么办 两岁宝宝认被子盖怎么办 小孩吃多了发烧怎么办 两岁宝宝拉蛔虫怎么办 吃了长蛆的东西怎么办 被蜱虫咬了又找不到虫子怎么办 木家具生黑虫子怎么办 吃了发霉的面包怎么办 种的韭菜有蛆怎么办 活狗身上长蛆虫怎么办 狗身上会有蛆虫怎么办 狗身上长满了蛆怎么办 房间墙上有很多小虫子怎么办 床上有许多小虫子怎么办? 店里有许多小虫子怎么办 房间潮湿有很多小虫子怎么办 家里潮湿墙上发霉长小虫怎么办? 房间有小飞虫子怎么办 狗被灭虫剂喷了怎么办 吃鸡玩久了手机屏幕很涩怎么办 超东卧室太阳晒怎么办 床头上的布破了怎么办 老年机全静音了怎么办 老年机手机不亮怎么办 70岁老人耳朵聋怎么办 血压太低了头晕怎么办 血压高忽然变低怎么办 血压高眼睛红了怎么办 高血压200降不下去.怎么办 高血压吃药降不下来怎么办 合肥房子卖了户口怎么办 吃了粽子胃难受怎么办 突然血压高怎么办需要吃药吗? 胃一阵阵疼然后拉肚子怎么办 橱子和墙壁不平怎么办