整理笔记翻出来的。。代码测试于2020年初,仅作备忘。
概念理解
Abstract Windowing Toolkit (AWT)
Component
能与用户交互的图形,例如button, checkbox, scrollbar, list
Container
是一个可以包含其他Component的Component
Panel
放compoent或者其他panel的容器
Window
在不同窗口可以执行不同程序,展示不同数据。
Frame
Frame包装了window
Canvas
是一个空白矩形区域,用户可以在上面绘画或者输入。继承自Component
Canvas和Panel的区别在于,Canvas是awt的,而Panel是swing的,而swing是以awt为基础的,所以理论上来说用Canvas会更轻量。但是性能差别不大?此外Canvas需要重写paint方法,而swing组件的paint()中实现了双缓冲,所以不需要重写paint,重写paintComponent
java.awt.Graphics2D继承了Graphics,提供了如下特性:
- 画基础图形的轮廓,draw
- 填充基础图形内部,fill
- 画文本,drawString
- 画指定图像,drawImage
因为是继承,所以Graphics的drawOval、fillRect等方法都可以用。为了使用Graphics2D的
特性,可以:
public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D) g;
...
}
The Graphics class supports only straight line segments. The Shape interface can support curves segments.
Geometric Primitives
Point2D没有面积,没有颜色,是用来制造形状的。
The Rectangle2D, RoundRectangle2D, Arc2D, and Ellipse2D primitives are all derived from the RectangularShape class.
QuadCurve2D 有两个端点和一个控制点
CubicCurve2D 有两个端点和两个控制点 贝塞尔曲线
GeneralPath画任意形状
Area类 操作两个Shape实例,可以进行union、intersection、subtraction
文本
文本一般直接用drawString方法,设置字体可以通过Graphics的setFont
查询本机可用字体?
GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] availFonts = g.getAvailableFontFamilyNames();
for (String s:availFonts)
System.out.println(s);
1.The TextLayout class manages text layout, highlighting, and hit detection. The facilities provided by TextLayout handle the most common cases, including strings with mixed fonts, mixed languages, and bidirectional text.
2.You can create the own GlyphVector objects by using the Font class and then rendering each GlyphVector object through the Graphics2D class. Thus, you can completely control how text is shaped and positioned.
Jframe 存放组件,相当于画框
Jpanel 存放图像,相当于画板
Graphics相当于画笔
使用
绘图步骤
- 创建相框JFrame对象jFrame
- 创建画板JPanel对象jPanel,重写paint()方法
- 在paint方法中,用画笔Graphics对象graphics的drawXXX()进行画图
- 将画板jPanel嵌入相框jFrame.add(jPanel)
- 设置相框为可见状态jFrame.setVisible(true)和相框大小
重写paint的那个类,也就是JFrame实例中保存的那个,可以是继承JPanel和Canvas的
基础
左上角是(0, 0),向下向右分别是y++和x++方向
例子1
绘制俩长方形。这里是写一个panel类,继承JPanel,重写里面的paint方法,然后在main里新建一个这样的实例,添加进frame即可。
// MyJpanel1.java
package hello;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class MyJpanel1 extends JPanel{
public void paint(Graphics g) {
super.paint(g);
Color c = g.getColor();
// drawRect(x, y, width, height)
g.drawRect(100, 100, 200, 100); // 绘制矩形,框的颜色默认黑的
g.setColor(Color.blue); // 填充的颜色
g.fillRect(100, 100, 200, 100);// 填充
g.setColor(c);
g.drawRect(400, 100, 200, 200);
g.setColor(Color.RED);
g.fillRect(400, 100, 200, 200);
//g.setColor(c);
}
}
package hello;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import hello.MyJpanel1;
public class DrawPlasmid {
public static void main(String[] args) {
JFrame jFrame = new JFrame();
MyJpanel1 test = new MyJpanel1();
jFrame.add(test);
jFrame.setLocationRelativeTo(null);
jFrame.setSize(500, 500);
jFrame.setVisible(true);
jFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent arg0) {
Window window = arg0.getWindow();
window.dispose();
}
});
}
}
那么paint函数里面可以用到的函数有:
画一条线段:
g.drawLine(100, 3, 50, 50); // 从(100, 3)到(50, 50)
默认的背景是灰色,线条的默认颜色是黑色
画一个点:
g.drawLine(50, 50, 50, 50);
画直角矩形:
g.drawRect(50, 50, 400, 200); // (x, y, width, height)都是整数
g.setColor(Color.blue); // 填充的颜色
g.fillRect(100, 100, 200, 100);// 填充
如果不关心框,真的可以只画填充块。
画圆角矩形:
除了指定左上顶点的坐标、长、高外,还要指定圆角弧的横向直径和圆角弧的纵向直径(类似椭圆?)
g.drawRoundRect(100, 50, 100, 50, 40, 25);
g.setColor(Color.blue);
g.fillRoundRect(300, 50, 50, 50, 25, 25); // 填充的函数类似
画圆:
将长、高、圆角弧横向直径和纵向直径设置为圆的半径,则画⚪
g.drawRoundRect(10, 50, 40, 40, 40, 40);
画一个突出显示的矩形:
draw3DRect的参数raised如果设为true就是凸出的,如果是false就是凹陷的。
g.setColor(c);
g.fillRect(50, 50, 100, 100);
g.draw3DRect(80, 100, 40, 25, true);
g.draw3DRect(80, 100, 40, 25, false);
这里只是框线,如果画色块:g.fill3DRect(80, 100, 40, 25, false);
左边是true,右边是false
画圆弧:
drawArc(int x,int y,int width,int height,int startAngle, int arcAngle)
画椭圆一部分的弧线。椭圆的中心是前面限定的这个矩形的中心,这个矩形外接这个椭圆,如下图所示。startAngle的单位是“度”,其实角度0度是3点钟方位。正值表示逆时针方向,负值表示顺时针方向,arcAngle表示经过的度数。
g.drawRect(10, 40, 50, 50);
g.drawArc(10, 40, 50, 50, 0, 90); // 从0度画90度,逆时针
g.setColor(Color.yellow);
g.fillArc(100, 100, 30, 30, 45, -180); // 从45度顺时针画180度
画多边形:
px1和py1并不要求最后一点与首点一致,是自动闭合的
int px1[] = {50, 90, 10, 50};
int py1[] = {10, 50, 50, 10};
g.setColor(Color.blue);
//g.drawPolygon(px1, py1, px1.length);
//g.drawPolygon(px1, py1, 3);
g.fillPolygon(px1, py1, 4);
也可以用多边形对象画多边形
Polygon p1 = new Polygon();
p1.addPoint(80, 40);
p1.addPoint(100, 10);
p1.addPoint(100, 20);
g.drawPolygon(p1);
// 两种Polygon的初始化方式
g.setColor(Color.yellow);
Polygon p2 = new Polygon(px1, py1, 3);
g.fillPolygon(p2);
擦除矩形块:
g.setColor(Color.yellow);
g.fillOval(50, 50, 100, 50); // 包裹椭圆的外接矩形顶点是(50,50),宽是100,高是50
g.clearRect(70, 70, 15, 10);
限定作图显示区域大小:
只有落在限定区域内的,才显示,超出的直接不显示。这个需要在绘制图形前设置好,如果在绘制后设置,无效。如果设置了多个,那么实际取的是多个的交集。
g.clipRect(0, 0, 100, 50);
g.clipRect(50, 25, 100, 50);
g.setColor(Color.green);
g.fillRect(0, 0, 200, 200);
这样的话:
复制图形:
最后两个参数表示移动方向。
g.copyArea(40, 50, 60, 70, -40, 80);