Java-Graphics类的绘图方法实现

Java-Graphics(画图类)

就比如画一个矩形,你给出矩形左上角坐标,再给出矩形长度和宽度就可以在JFrame上画出来一个矩形

除了矩形之外,还可以画椭圆、圆、圆弧、线段、多边形、图像等

下面给出画矩形的代码

Rect.java

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Rect extends JPanel{
    public static Color myColor = Color.RED;
    public static int myX = 10;
    public static int myY = 10;
    public static int myWidth = 100;
    public static int myHeight = 100;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(myColor);
        g.fillRect(myX+100,myY+100,myWidth,myHeight);    //画矩形着色块
        g.drawRect(myX,myY,myWidth,myHeight);    //画矩形线框
    }
}

Main.java

import java.awt.Color;

import javax.swing.JFrame;


public class Main{
    //Note how we don't need to extend the Rect class (It just adds confusion)
    public static void main(String[] args ) {

        JFrame window = new JFrame("test");
        window.setSize(1000, 800);
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        window.setResizable(false);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //create Rect
        Rect rect = new Rect();
        //set the size of the new panel
        //rect.setPreferredSize(new Dimension(800, 600));
        //add the rect to your JFrame
        window.add(rect);


        //如果你改变了Rect的静态属性color的值,它会同步更新,你把下面的代码注释了还可以画出矩形,那样的话画出来的图形就是红色的
        Rect.myColor = Color.BLUE;
        Rect.myX = 400;
        Rect.myY = 400;
        //加上下面,但是感觉加不加没啥差距,,学废了,,,,
        rect.repaint();
    }
}

repaint的一些问题

下面代码输出的结果是错误的

// In MyPanel.java
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    // Draw something
    mypanel_count++;
}

// In Test.java
public void testLargeData()
{
    while (notDone)
    {
        panel.repaint();
        // do huge work
        test_count++;
        System.out.println("Test_count: " + test_count + ", MyPanel_count: " + mypanel_count);
    }
}

// 程序Output !!!
Test_count: 752, MyPanel_count: 23
Test_count: 753, MyPanel_count: 23
Test_count: 754, MyPanel_count: 23
Test_count: 755, MyPanel_count: 24

当我将 panel.repaint()更改为 panel.paintComponent(panel.getGraphics()),输出正确:

//正确输出如下
Test_count: 752, MyPanel_count: 752
Test_count: 753, MyPanel_count: 753
Test_count: 754, MyPanel_count: 754
Test_count: 755, MyPanel_count: 755

paintComponent 方法虽然有效,但是有些时候也会错误!

为什么会这样?

这意味着允许AWT / Swing通过合并快速连续请求的重绘来优化重绘。还有一个 repaint( (长时间) 方法,该方法可让您控制AWT / Swing在完成重新绘制请求后等待的时间。但是,它仍然可以合并请求,特别是如果您是循环执行的话。 

解决办法

使用 paintImmediately(...)但是您必须在事件分配线程中进行所有处理,如下所示:

  SwingUtilities.invokeLater(new Runnable(){
 public void run(){
 while(notDone){
 //是否处理
 panel.paintImmediately(...); 
} 
} 
}); 

paintImmediately函数:
public void paintImmediately(Rectangle r)
  Paints the specified region now.
  Parameters:
    r - a Rectangle containing the region to be painted

要使面板在每次迭代时都重新粉刷,您必须等待粉刷发生,然后继续循环。这意味着您需要在处理线程(循环)和AWT / Swing线程之间进行一些同步。大致来说,您可以例如 wait() 在循环结束时在面板对象上,如果自从上次调用 repaint(),然后调用 面板的 paintComponent()方法末尾的notifyAll() 。但是,这可能很难正确实现,因此,仅在确实需要"实时"重绘组件时才应这样做。

好了,不谈论repaint的问题了,我们来说画其他类型图形的方法

就只需要改下面函数里面的代码就可以了

@Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(myColor);
        g.fillRect(myX+100,myY+100,myWidth,myHeight);    //画矩形着色块
        g.drawRect(myX,myY,myWidth,myHeight);    //画矩形线框
    }

画圆角矩形

画圆角矩形也有两个方法:

/**
 * 用此图形上下文的当前颜色绘制圆角矩形的边框。
 * 矩形的左边缘和右边缘分别位于 x 和 x + width。
 * 矩形的上边缘和下边缘分别位于 y 和 y + height。
 */
public abstract void drawRoundRect(int x, int y, int width, int height,
        int arcWidth, int arcHeight)

/**
 * 用当前颜色填充指定的圆角矩形。
 * 矩形的左边缘和右边缘分别位于 x 和 x + width - 1。
 * 矩形的上边缘和下边缘分别位于 y 和 y + height - 1。
 */
public abstract void fillRoundRect(int x, int y, int width, int height,
        int arcWidth, int arcHeight)

参数 arcWidth 表示4个角弧度的水平直径,arcHeight 表示4个角弧度的垂直直径。

以下代码是画矩形的例子:

g.drawRoundRect(10,10,150,70,40,25); // 画一个圆角矩形

g.setColor(Color.blue); g.fillRoundRect(80,100,100,100,60,40); // 填充一个圆角矩形块

g.drawRoundRect(10,150,40,40,40,40); // 画圆

g.setColor(Color.red); g.fillRoundRect(80,100,100,100,100,100);//画圆块

可以用画圆角矩形方法画圆形,当矩形的宽和高相等,圆角弧的横向直径和圆角弧的纵向直径也相等,并等于矩形的宽和高时,画的就是圆形。参见上述例子中的注释,前一个是画圆,后一个是涂圆块。

画多边形

多边形是用多条线段首尾连接而成的封闭平面图。多边形线段端点的x坐标和y坐标分别存储在两个数组中,画多边形就是按给定的坐标点顺序用直线段将它们连起来。以下是画多边形常用的两个方法:

/**
 * 绘制一个由 x 和 y 坐标数组定义的闭合多边形。每对 (x, y) 坐标定义一个点。
 */
public abstract void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);

/**
 * 填充由 x 和 y 坐标数组定义的闭合多边形。
 */
public abstract void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)

绘制由 nPoint 个线段定义的多边形,其中前 nPoint - 1 个线段是 1 ≤ i ≤ 时从 (xPoints[i - 1], yPoints[i - 1]) 到 (xPoints[i], yPoints[i]) 的线段。如果最后一个点和第一个点不同,则图形会通过在这两点间绘制一条线段来自动闭合。

以下代码是画多边形的例子:

int px1[]={50,90,10,20};//首末点相重,才能画多边形

int py1[]={10,50,50,20};

int px2[]={140,180,170,180,140,100,110,140};

int py2[]={5,25,35,45,65,35,25,5};

g.setColor(Color.blue);

g.fillPolygon(px1,py1,4);

g.setColor(Color.red);

g.drawPolygon(px2,py2,8);

也可以用多边形对象画多边形。用多边形类Polygon创建一个多边形对象,然后用这个对象绘制多边形。Polygon类的主要方法:

Polygon()  // 创建空的多边形。 
Polygon(int[] xpoints, int[] ypoints, int npoints)  // 根据指定的参数构造并初始化新的 Polygon。 

public void addPoint(int x, int y) // 将一个坐标点加入到Polygon对象中。

使用Polygon多边形对象绘制多边形的方法:

public void drawPolygon(Polygon p) // 绘制多边形。

public void fillPolygon(Polygon p) // 填充多边形。

例如,以下代码,画一个三角形和填充一个黄色的三角形。注意,用多边形对象画封闭多边形不要求首末点重合。

Polygon ponlygon1=new Polygon();    
polygon1.addPoint(50,10);   
polygon1.addPoint(90,50);   
polygon1.addPoint(10,50);   
g.drawPolygon(polygon1);    

int x[]={140,180,170,180,140,100,110,100};  
int y[]={5,25,35,45,65,45,35,25};   
Polygon polygon2 = new Polygon(x,y,8);  
g.setColor(Color.yellow);   
g.fillPolygon(polygon2);

画图像

绘制图像的常用方法:

boolean drawImage(Image img, int x, int y, ImageObserver observer) 
boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) 
boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) 
boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer) 

参数:

Image img – 需要绘制的图像。

int x, int y – 图像左上角坐标。

int width, int height – 图像的宽度和高度。

Color bgcolor – 背景色,即图像下面的颜色。如果图像包含透明象素时这会有用,图像将在指定颜色背景下显示。

ImageObserver observer – 一个实现ImageObserver 接口的对象。它将该对象登记为一个图像观察者,因此当图像的任何新信息可见时它被通知。大多组件可以简单的指定this。

组件可以指定this作为图像观察者的原因是Component 类实现了ImageObserver 接口。当图像数据被加载时它的实现调用repaint方法,这通常是你所期望的。

drawImage 方法只要要显示的图像数据已经加载完就返回。如果你要确保drawImage只绘制完整的图像,那么你需要跟踪图像的加载。

例如,绘制一张图片:

Image img = Toolkit.getDefaultToolkit().getImage("img/monster.gif");
g.drawImage(img, 510, 5, 200, 200, Color.LIGHT_GRAY, this);

画线段:在窗口中画一条线段,可以使用Graphics类的drawLine()方法:

/**
 * 在此图形上下文的坐标系中,使用当前颜色在点 (x1, y1) 和 (x2, y2) 之间画一条线
 * 
 * @param x1
 *            第一个点的 x 坐标
 * @param y1
 *            第一个点的 y 坐标
 * @param x2
 *            第二个点的 x 坐标
 * @param y2
 *            第二个点的 y 坐标
 */
public abstract void drawLine(int x1, int y1, int x2, int y2)

例如,以下代码在点(3,3)与点(50,50)之间画线段,在点(100,100)处画一个点。

g.drawLine(3,3,50,50); //画一条线段

g.drawLine(100,100,100,100); //画一个点。

更多见:

JavaGraphics类的绘图方法

原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/14061828.html