第19章JAVA绘图
19.1JAVA绘图类
绘图是高级程序设计中非常重要的技术
19.1.1Graphics类
Graphics类是所有图形上下文的抽象基类,它允许应用程序在组件以及闭屏图片上进行绘制
Graphics类封装了JAVA支持的基本绘图操作所需的状态信息,主要包括颜色,字体,画笔,文本,图像等。
19.1.2Graphics2D类
使用Graphics类可以完成简单的图形绘制任务,但功能有限,无法改变线条的粗细,不能对图片进行
19.2绘制图形
JAVA可以分别使用Graphics类和Graphics2D类绘制图形
例题19.1
package java19lx;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Demo19_1 extends JFrame {
private final int W=80;//高
private final int H=80;//宽
public Demo19_1() {
initialize();//调用初始方法
}
private void initialize() {//初始化方法
setSize(300,200);//设置窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭模式
setContentPane(new DrawPanel());//设置窗体面板为绘图面板对象
setTitle("绘图实例 1");//设置窗体标题
}
class DrawPanel extends JPanel{//创建绘图面板
public void paint(Graphics g) {//重写绘制方法
g.drawOval(10, 10, W, H);//绘制第1个图形
g.drawOval(80, 10,W, H);//绘制第2个图形
g.drawOval(150, 10,W, H);//绘制第3个图形
g.drawOval(50, 70, W, H);//绘制第4个图形
g.drawOval(120, 70,W, H);//绘制第5个图形
}
}
public static void main(String[]args) {
new Demo19_1().setVisible(true);
}
}
结果
Graphics类常用的图形绘制方法
Graphics2D类是在继承Graphics类的基础上编写的,包含了Graphics类的绘制方法,并添加了更强的功能,在绘制绘图类时推荐使用,Graphics2D类可以分别使用不同的类,表示不同的形状。
要绘制指定形状的图形,需要先创建并初始化该图形类的对象,且这些类图形类必须是Shape接口的实现类,然后使用Graphics2D类的draw()方法绘制该图形对象或者使用fil(0l方法填充该图形对象语法格式如下
draw(Shape form)
fill(Shape form)
form是Shape接口的对象
例题19.2
package java19lx;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Demo19_2 extends JFrame {
public Demo19_2(){//初始化方法
setTitle("绘图实例2");//设置窗体标题
setSize(300,300);//设置窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭模式
add(new CanvasPanel());//设置窗体面板为绘图面板对象
}
class CanvasPanel extends JPanel{//绘图面板
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D)g;
Shape[]shapes=new Shape[4];//声明图形数组
shapes[0]=new Ellipse2D.Double(5,5,100,100);//创建圆形对象
shapes[1]=new Rectangle2D.Double(110,5,100,100);//创建矩形对象
shapes[2]=new Rectangle2D.Double(15,15,80,80);//创建矩形对象
shapes[3]=new Ellipse2D.Double(120,15,80,80);//创建圆形对象
for(Shape shape:shapes) {//遍历图形数组
Rectangle2D bounds=shape.getBounds2D();
if(bounds.getWidth()==80) {
g2.fill(shape);//填充图形
}
else {
g2.draw(shape);//绘制图形
}
}
}
}
public static void main(String[] args) {
new Demo19_2().setVisible(true);
}
}
结果
19.3绘图颜色与画笔属性
19.3.1设置颜色
使用 Color 类可以创建任意颜色的对象,不用担心平台是否支持改颜色,因为 Java 以跨平台和与硬件无关的方式支持颜色管理。
19.3.2设置画笔
默认情况下,Graphics 类使用的画笔属性是粗细为1个像素的正方形,而 Graphics2D 类可以调用 setStroke() 方法设置属性,如果改变线条的粗细、虚实,定义线端点的形状、风格等。 setStroke() 方法必须接受一个Stroke 接口的实现类对象作参数,java.awt 包中提供了BasicStroke 类,它实行了了 Stroke 接口,并且通过不同的构造方法创建画笔不同对象。
19.4绘制文本
19.4.1设置字体
Java使用 Font 类封装了字体的大小、样式等属性,该类在 java.awt 包中定义,其构造方法可以指定字体的名称、大小和样式3个属性。
19.4.2显示文字
Graphics2D 类提供了 drawString()方法,使用该方法可以实现图形上下文的文本绘制,从而实现在图片上显示文字的功能。
例题19.3
package java19lx;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Date;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java19lx.Demo19_2.CanvasPanel;
public class Demo19_3 extends JFrame{
public Demo19_3() {
setSize(230,140);//设置窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭模式
add(new CanvasPanel());//设置窗体面板为绘图面板对象
setTitle("绘图文本");//设置窗体标题
}
class CanvasPanel extends JPanel{
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D) g;
Rectangle2D rect=new Rectangle2D.Double(10, 10, 200, 80);
g2.setColor(Color.CYAN);//设置当前绘图颜色
g2.fill(rect);//填充矩形
Font font=new Font("宋体",Font.BOLD,16);
g2.setColor(Color.BLUE);//设置当前绘图颜色
g2.setFont(font);//设置字体
g2.drawString("现在时间是", 20, 30);//绘制文本
Date date=new Date();
g2.drawString(String.format("%tr", date), 50, 60);//绘制时间文本
}
}
public static void main(String[] args) {
new Demo19_3().setVisible(true);
}
}
结果:
19.5显示图片
绘图不仅可以绘制图形和文本,还处理。
例题19.4
可以使用 drawImage() 方法将图片资源显示到绘图上下文中,而且可以实现各种特效
package java19lx;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Demo19_4 extends JFrame{
Image img;//展示的图片
public Demo19_4(){
try {
img=ImageIO.read(new File("src/徽章.png/"));//读取图片文件
}catch(IOException e){
e.printStackTrace();
}
setSize(440,300);//设置窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭模式
add(new CanvasPanel());//设置窗体面板为绘图面板对象
setTitle("绘制图片");//设置窗体标题
}
class CanvasPanel extends JPanel{
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D)g;
g2.drawImage(img, 100, 0, this );//显示图片
//x,y,哪个图片
}
}
public static void main(String [] args) {
new Demo19_4().setVisible(true);
}
}
结果
19.6图像处理
19.6.1放大与缩小
使用了 drawImage() 方法将图片以原始大小显示在窗体中,要想实现图片的放大与缩小,则需要使用他的重载方法。
例题19.5
package java19lx;
import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class Demo19_5 extends JFrame {
Image img;
private int W,H;
private JSlider jSlider;
public Demo19_5() {
try {
img=ImageIO.read(new File("src/徽章.png"));//读取图片
}catch(IOException e) {
e.printStackTrace();
}
CanvasPanel can=new CanvasPanel();
jSlider=new JSlider();
jSlider.setMaximum(1000);
jSlider.setValue(100);
jSlider.setMinimum(1);
jSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
can.repaint();
}
});
JPanel center=new JPanel();
center.setLayout(new BorderLayout());
center.add(jSlider,BorderLayout.SOUTH);
center.add(can,BorderLayout.CENTER);
setContentPane(center);
setBounds(100,100,800,600);//窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭模式
setTitle("绘制图片");
}
class CanvasPanel extends JPanel{
public void paint(Graphics g) {
int newW=0,newH=0;
W=img.getWidth(this);//获取图片宽度
H=img.getHeight(this);//获取图片高度
float value=jSlider.getValue();//滑块组件的取值
newW=(int)(W*value/100);//计算图片放大后的宽度
newH=(int)(H*value/100);//计算图片放大后的高度
g.drawImage(img,0,0,newW,newH,this);//绘制指定大小的图片
}
}
public static void main(String[] args) {
new Demo19_5().setVisible(true);
}
}
结果:
19.6.2图像翻转
图像的翻转需要使用 drawImage() 方法的另一个重载方法。
此方法总是用来非缩放的图像来呈现缩放的矩形,并动态地执行所需要的缩放。此操作不使用缓存的缩放图像。执行图像从源到目标的缩放,要将源矩形的第一个坐标映射到目标矩形的第一个坐标,源矩形的第二个坐标映射到目标矩形的第二个坐标,按需要缩放和翻转子图像,以保持这些映射关系。
例题19.6
package java19lx;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class Demo19_6 extends JFrame {
private Image img;
private int dx1,dy1,dx2,dy2;
private int sx1,sy1,sx2,sy2;
private int W=300,H=200;
private JButton v=null;
private JButton h=null;
private CanvasPanel canvasPanel=null;
public Demo19_6() {
try {
img=ImageIO.read(new File("src/徽章.png"));
}catch(IOException e) {
e.printStackTrace();
}
dx2=sx2=W;
dy2=sy2=H;
v=new JButton("垂直旋转");
h=new JButton("水平翻转");
JPanel botton=new JPanel();
botton.add(h);
botton.add(v);
Container c=getContentPane();
c.add(botton,BorderLayout.SOUTH);
canvasPanel =new CanvasPanel();
c.add(canvasPanel,BorderLayout.CENTER);
addListener();
setBounds(100,100,300,260);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("图片翻转");
}
private void addListener() {
v.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sy1=Math.abs(sy1-H);
sy2=Math.abs(sy2-H);
canvasPanel.repaint();
}
});
h.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
sx1=Math.abs(sx1-W);
sx2=Math.abs(sx2-W);
canvasPanel.repaint();
}
});
}
class CanvasPanel extends JPanel{
public void paint(Graphics g) {
g.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, this);
}
}
public static void main(String[] args) {
new Demo19_6().setVisible(true);
}
}
结果:
19.6.3图像旋转
图像旋转需要调用 Graphics2D 类的 rotate()方法,该方法将根据指定的弧度旋转图像。
例题19.7
package java19lx;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Demo19_7 extends JFrame {
private Image img;
private Demo19_7() {
try {
img=ImageIO.read(new File("src/徽章.png"));//读取图片
}catch(IOException e) {
e.printStackTrace();
}
setBounds(100,100,400,350);//设置窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭模式
setTitle("图片旋转");//设置窗体标题
add(new CanvasPanel());
}
class CanvasPanel extends JPanel{
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D) g;
g2.rotate(Math.toRadians(5));//旋转5°,传入的是弧度值
g2.drawImage(img, 70, 10, 300, 200, this);
g2.rotate(Math.toRadians(5));
g2.drawImage(img, 70, 10, 300, 200, this);
g2.rotate(Math.toRadians(5));
g2.drawImage(img, 70, 10, 300, 200, this);
}
}
public static void main(String[] args) {
new Demo19_7().setVisible(true);
}
}
结果:
19.6.4图像倾斜
可以使用 Graphics2D 类提供的 shear()方法设置绘图的倾斜方向,从而使图像实现倾斜的效果。
例题19.8
package java19lx;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Demo19_8 extends JFrame{
private Image img;
public Demo19_8() {
try {
img=ImageIO.read(new File("src/徽章.png"));//读取图片
}catch(IOException e) {
e.printStackTrace();
}
setBounds(100,100,400,300);//窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭模式
setTitle("图片倾斜");//窗体标题
add(new CanvasPanel());
}
class CanvasPanel extends JPanel{
public void paint(Graphics g) {
Graphics2D g2=(Graphics2D)g;
g2.shear(0.3,0);//倾斜30%
g2.drawImage(img,0,0,300,200,this);
}
}
public static void main(String[] args) {
new Demo19_8().setVisible(true);
}
}