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. Flutter 基础组件:文本、字体样式

    // 文本.字体样式 import 'package:flutter/material.dart'; class TextFontStyle extends StatelessWidget { // ...

  2. Hash Tables and Hash Functions

    Reference: Compuer science Introduction: This computer science video describes the fundamental princ ...

  3. nodejs中的文件系统

    . 目录 简介 nodejs中的文件系统模块 Promise版本的fs 文件描述符 fs.stat文件状态信息 fs的文件读写 fs的文件夹操作 path操作 简介 nodejs使用了异步IO来提升服 ...

  4. html2canvas canvas webgl 截图透明空🤣

    1. React用这个插件html2canvas完成div截图功能,div里面嵌套canvas,返回base64是透明图片. html2canvas(document.getElementById(& ...

  5. 【Java】计算机软件、博客的重要性、编程语言介绍和发展史

    之前学得不踏实,重新复习一遍,打扎实基础中. 记录 Java核心技术-宋红康_2019版 & Java零基础学习-秦疆 文章目录 软件开发介绍 软件开发 什么是计算机? 硬件及冯诺依曼结构 计 ...

  6. 【Linux】linux中用vim来比较文件内容不同

    1. 使用vim的比较模式打开两个文件: vim -d file1 file2 或 vimdiff file1 file2 2. 如果已经打开了文件file1,再打开另一个文件file2进行比较: : ...

  7. 天天用SpringBoot居然还不知道它的自动装配的原理?

    引言 最近有个读者在面试,面试中被问到了这样一个问题"看你项目中用到了springboot,你说下springboot的自动配置是怎么实现的?"这应该是一个springboot里面 ...

  8. 全球城市ZoneId和UTC时间偏移量的最全对照表

    前言 你好,我是A哥(YourBatman). 如你所知,现行的世界标准时间是UTC世界协调时,时区已不直接参与时间计算.但是呢,城市名称or时区是人们所能记忆和容易沟通的名词,因此我们迫切需要一个对 ...

  9. 【Android】编译报错 Annotation processors must be explicitly declared now 解决方案

    问题 在网上下载一个demo,因为版本久远,里面添加了本地 Butter Knife 的jar包,在编译时报错 Annotation processors must be explicitly dec ...

  10. mysql+MHA高可用

    MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀 ...