Java学习笔记--Swing2D图形

时间:2021-10-27 11:31:06

1.处理2D图形

要想使用java 2D库绘制图形,需要获得一个Graphics2D类对象。这个类是Graphics类的子类。
paintComponent方法自动获得一个Graphics2D类对象,我们只需要进行一次类型转换。

public void paintComponent(Graphics g){
    Graphics2d g2 = (Graphics2D) g;
}

 

Java 2D库采用面向对象的方式将几何图形组织起来。包含描述直线、矩形、椭圆的类(当然也支持更复杂的图形):

Line2D Rectangle2D Ellipse2D
这些类全部实现了Shape接口
想绘制图形,
(1)先要创建一个实现了Shape接口的类的对象,
(2)然后调用Graphics2D类中的draw方法

每个图形类有两个版本,如 Rectangle2D.Float, Rectangle2D.Double

(一般来说用float即可,精度足够,可以节约空间,增加Double是因为精度丢失会有错误,当然也可以用强制类型转换)

2D矩形类
                     ┌Rectangle2D.Float
Rectangle2D-┤
                     └Rectangle2D.Double

因此,创建Rectangle2D.Float对象需要提供float型数值坐标。Rectangle2D.Double提供double型坐标。

Rectangle2D.Float floatRect = new Rectangle2D.Float(10.0F,25.0F,22.5F,20.0F);
Rectangle2D.Double doubleRect = new Rectangle2D.Double(10.0,25.0,22.5,20.0);

实际可以使用

Rectangle2D floatRect = new Rectangle2D.Float(10.0F,25.0F,22.5F,20.0F);
Rectangle2D doubleRect = new Rectangle2D.Double(10.0,25.0,22.5,20.0);

 

Point2D类也有两个子类

Point2D p = new Point2D.Double(10,20); 

Rectangle2D和Ellipse2D类都是由公共超类RectangularShape继承而来。因为椭圆也有矩形边界。
RectangularShape常用的方法有  getWidth,  getHeight ,  getCenterX,  getCenterY

  

构造矩形

Rectangle2D rect = new Rectangle2D.Double(lux,luy,rdx,rdy);

表示 构造左上角位于(lux , luy)右下角位于(rdx , rdy)的矩形
但如果顶点不是左上角时可以这样构造:

Rectangle2D rect = new Rectangle2D.Double();//先构造一个空矩形
rect.setFrameFromDiagonal(px,py,qx,qy);

或者已知顶点为Point2D类型的两个对象p、q,可以这样调用

rect.setFrameFromDiagonal(p ,q);

 

构造椭圆

Ellipse2D e = new Ellipse2D.Double(150,200,100,50);
表示 用左上角位于(150,200)、宽100、高50的外接矩形构造一个椭圆
知道椭圆中心点时可以这样

Ellipse2D e = new Ellipse2D.Double(centerX-width/2,centerY-height/2,width,height);

 

构造直线 

Line line = new Line2D.Double(start,end);
Line line = new Line2D.Double(startx,starty,endx,endy);

 

例子:

public class DrawTest {
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable(){
			public void run (){
				JFrame frame = new JFrame();
				frame.setTitle("2D图形");
				
				frame.add(new DrawComponent());		//添加自己的JComponent
				frame.setSize(400,400);	//设置窗口大小
				
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setVisible(true);
			}
			});
	}
}

class DrawComponent extends JComponent{
	public void paintComponent(Graphics g){
		final int DEFAULT_WIDTH = 400;
		final int DEFAULT_HEIGHT = 400;
		Graphics2D g2 = (Graphics2D)g;
		
		double leftx = 100;
		double topy =100;
		double width =200;
		double height = 150;
		
		//画矩形
		Rectangle2D rect = new Rectangle2D.Double(leftx,topy,width,height);
		g2.draw(rect);
		
		//画椭圆
		Ellipse2D ellip = new Ellipse2D.Double();
		ellip.setFrame(rect);
		g2.draw(ellip);
		
		//画一条直线
		g2.draw(new Line2D.Double(leftx,topy,leftx+width,topy+height));		
		
		//画另一个椭圆
		double centerx = rect.getCenterX();
		double centery = rect.getCenterY();
		double radius = 150 ;		
		Ellipse2D circle = new Ellipse2D.Double();
		circle.setFrameFromCenter(centerx,centery,centerx+width,centery+height);
		g2.draw(circle);
	}
}

  

2.使用颜色 

Graphics2D类的setPaint方法可以为图形环境上的所有后续的绘制操作选择颜色,(setColor等同于setPaint)例如:

g2.setPaint(Color.RED);
g2.drawString("Warning",100,100);

只需要将调用draw替换为调用fill就可以用一种颜色填充一个封闭图形(例如:矩形或者椭圆形)

Rectangle2D rect = new Rectangle2D.Double(leftx,topy,width,height) ; 
g2.setPaint(Color.RED);
g2.fill(rect);    //fills rect with red color

想要设置背景颜色,就需要使用Component类中的setBackground方法。component类是JComponent类的祖先

JComponent类setBackground需要做的工作
第一,你需要一个UI
第二,你必须将其设置为非透明。
第三,调用super的paintComponent方法。

注:如果使用JPanel则不需UI与设置非透明,因为JPanel就是不透明的

public class DrawColor {
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable(){
			public void run(){
				JFrame frame = new JFrame();
                frame.setTitle("2D图形颜色填充");
                //frame.setBackground(Color.black);
                
                MyComponent mp = new MyComponent();
                //mp.setOpaque(true);//将component设置为不透明
                mp.setBackground(Color.blue);                
                frame.add(mp);
                
                frame.setSize(400,400); //设置窗口大小                
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
			}
		});
	}
}

/*setBackground需要做的工作
	第一,你需要一个UI
	第二,你必须将其设置为非透明。
	第三,调用super的paintComponent方法。
*/
class MyComponent extends JComponent{
	public MyComponent() {
        super();
        setUI(new ComponentUI(){});	//设定一个UI
        setOpaque(true);//将component设置为不透明
    }
	public void paintComponent(Graphics g){
		super.paintComponent(g);//调用super的paintComponent方法
		Graphics2D g2 = (Graphics2D)g;

        //画矩形
        Rectangle2D rect = new Rectangle2D.Double(100,100,200,150);
        g2.setPaint(Color.RED);	//设置颜色
        g2.fill(rect);	//画图
	}
}