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类的绘图方法

Java-Graphics类的绘图方法实现的更多相关文章

  1. Java Graphics2D类的绘图方法

    Graphics2D继承自Graphics,它扩展了Graphics的绘图功能,拥有更强大的二维图形处理能力,提供对几何形状.坐标转换.颜色管理以及文字布局等更精确的控制. Graphics2D定义了 ...

  2. Java知多少(98)Graphics类的绘图方法

    Graphics类提供基本绘图方法,Graphics2D类提供更强大的绘图能力.本节讲解Graphics类,下节讲解Graphics2D. Graphics类提供基本的几何图形绘制方法,主要有:画线段 ...

  3. 十一. 图形、图像与多媒体4.Graphics类的绘图方法

    Graphics类提供基本绘图方法,Graphics2D类提供更强大的绘图能力.本节讲解Graphics类,下节讲解Graphics2D. Graphics类提供基本的几何图形绘制方法,主要有:画线段 ...

  4. Java知多少(99)Graphics2D类的绘图方法

    Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...

  5. 十一. 图形、图像与多媒体5.Graphics2D类的绘图方法

    Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供.坐标转换.颜色管理以及文字布局等更精确的 ...

  6. Java的Graphics类进行绘图的方法详解

    Graphics类提供基本绘图方法,Graphics2D类提供更强大的绘图能力. Graphics类提供基本的几何图形绘制方法,主要有:画线段.画矩形.画圆.画带颜色的图形.画椭圆.画圆弧.画多边形等 ...

  7. JavaGraphics类的绘图方法

    Graphics类提供基本绘图方法,Graphics类提供基本的几何图形绘制方法,主要有:画线段.画矩形.画圆.画带颜色的图形.画椭圆.画圆弧.画多边形.画字符串等. 1. 画线段:在窗口中画一条线段 ...

  8. Java AtomicInteger类的使用方法详解_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下: public class Samp ...

  9. 第4篇-JVM终于开始调用Java主类的main()方法啦

    在前一篇 第3篇-CallStub新栈帧的创建 中我们介绍了generate_call_stub()函数的部分实现,完成了向CallStub栈帧中压入参数的操作,此时的状态如下图所示. 继续看gene ...

随机推荐

  1. php利用腾讯ip分享计划获取地理位置示例分享

    <?php function getIPLoc_QQ($queryIP){ $url = 'http://ip.qq.com/cgi-bin/searchip?searchip1='.$quer ...

  2. linux系统修改Swap分区【转】

    在装完Linux系统之后自己去修改Swap分区的大小(两种方法) 在安装完Linux系统后,swap分区太小怎么办,怎么可以扩大Swap分区呢?有两个办法,一个是从新建立swap分区,一个是增加swa ...

  3. 分装button组件引发的内存泄漏问题

    这个问题其实一开始在vue里写的时候并没有注意到这一点,也没有报错,直到在react里写的时候给我报了一堆错之后,经各种磨烂之后最终找到是分装button组件的问题,既然找到问题在哪就好办了 直接先上 ...

  4. SonarQube学习(六)- SonarQube之扫描报告解析

    登录http://192.16.1.105:9000,加载项目扫描情况 点击项目名称,查看报告总览 开发人员主要关注为[问题]标签页. 类型 主要关注为bug和漏洞. 其中bug是必须要修复的,漏洞是 ...

  5. C#中foreach的实现原理

    C#中foreach的实现原理 在探讨foreach如何内部如何实现这个问题之前,我们需要理解两个C#里边的接口,IEnumerable 与 IEnumerator. 在C#里边的遍历集合时用到的相关 ...

  6. CTFshow-萌新赛杂项_签到

    查看网页信息 http://game.ctf.show/r2/ 把网页源码下载后发现有大片空白 使用winhex打开 把这些16进制数值复制到文件中 把20替换为0,09替换为1后 得到一串二进制数值 ...

  7. bash5.0参考手册

    Bash Reference Manual a.summary-letter { text-decoration: none } blockquote.indentedblock { margin-r ...

  8. 小试牛刀ElasticSearch大数据聚合统计

    ElasticSearch相信有不少朋友都了解,即使没有了解过它那相信对ELK也有所认识E即是ElasticSearch.ElasticSearch最开始更多用于检索,作为一搜索的集群产品简单易用绝对 ...

  9. 命令模式与go-redis command设计

    目录 一.什么是命令(Command)模式 二.go-redis command相关代码 三.总结 一.什么是命令(Command)模式 命令模式是行为型设计模式的一种,其目的是将一个请求封装为一个对 ...

  10. spring源码分析之玩转ioc:bean初始化和依赖注入(一)

    最近赶项目,天天加班到十一二点,终于把文档和代码都整完了,接上继续整. 上一篇聊了beanProcess的注册以及对bean的自定义修改和添加,也标志着创建bean的准备工作都做好了,接下来就是开大招 ...