2.4 渲染图元
Rendering Graphics Primitives
Graphics2D为图形、文本、图像提供了渲染方法:
(1) draw - 在Graphics2D上下文中通过Stroke和Paint对象描绘图形路径;
(2) fill - 在上下文中使用Paint填充图形;
(3) drawString - 在上下文中使用Paint渲染指定的字符串;
(4) drawImage - 渲染指定图像
为了能描绘并填充图形,你需要调用draw和fill方法。
Graphics2D在先前的JDK版本中同样支持draw和fill方法,例如drawOval和fillRect.
2.4.1 绘制图形
Draw a Shape
图形的轮廓能通过Graphics2D.draw方法来渲染。先前的JDK中支持 的draw方法还有:drawLine、drawRect、drawRoundRect、drawOval、drawAcr、drawPolyline、 drawPolygon和draw2DRect。
当一个图形被绘制,它的路径通过Graphics2D上下文中的Stroke对象来描边。在上下文中通过设置一个合适的BasicStroke对象,你可以绘制任何宽度和样式的线条。BasicStroke同样定义了线条的端部和结合点的属性。
渲染图形的轮廓的步骤:
(1) 创建一个BasicStroke对象;
(2) 调用Graphics2D.setStroke方法;
(3) 创建Shape;
(4) 调用Graphics2D.draw(shape);
下面的示例中,GeneralPath对象用来定义一个五星然后用BasicStroke对象来定义五星的线条和结合点属性:
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g ;
//创建并设置stroke
g2.setStroke(new BasicStroke( 4.0f ));
//使用GeneralPath对象创建一个五星
GeneralPath p = new GeneralPath(GeneralPath.NON_ZERO);
p.moveTo( - 100.0f, -25.0f );
p.lineTo(+100.0f, -25.0f );
p.lineTo( - 50.0f, -25.0f);
p.lineTo( +0.0f, -100.0f);
p.lineTo(+50.0f , +100.0f);
p.closePath();
//translate origin towards center of canvas
g2.translate(100.0f, 100.0f);
//渲染五星的路径
g2.draw(p);
}
2.4.2 填充图形
Filling a Shape
Graphics2D.fill方法可用来填充任何的图形。当填充一个图形时,它的图形路径内部的的区域将被Paint的当前属性——Color、TexturePaint、及GradientPaint渲染。
先前的JDK版本中支持的填充方法有:fillRect、fill2DRect、fillRoundRect fillOval、fillArc、fillPolygon、clearRect。
填充一个图形的基本步骤:
(1) 在上下文中使用Graphics2D.setColor或Graphics2D.setPaint设置填充的颜色和模式;
(2) 创建一个Shape对象;
(3) 调用Graphics2D.fillRect渲染图形对象;
在下面的示例中,调用setColor来为一个Rectangle2D对象定义一个绿色填充:
public void paint(Graphics g){
Graphics2D g2 = (Graphcs2D) g;
g2.setPaint(Color.green);
Rectangle2D r2 = new Rectangle2D.Float(25,25,150,250);
g2.fill(r2);
}
2.4.3 渲染文本
Rendering Text
为了渲染字符串,你可以调用Graphics2D.drawString并把它传递到你要渲染的字符串。关于渲染文本和选择字体的信息,请参见"字体和文本布局(Fonts and Text Layout)"。
2.4.4 渲染图像
Rendering Images
为了渲染图像,你需要创建Image对象,并调用Graphics2D.drawImage.更多关于处理和渲染图片的信息请参见"图形渲染(Imaging)"。
2.5 定义自定义的混合规则
Defining Custom Composition Rules
通过实现Composite和CompositeContext接口,你可以创建一个全新的混合操作类型。一个Composite对象提供的CompositeContext对象实际上保持了混合状态并完成混合工作。可以从Composite中创建多种CompositeContext对象来保持在不同环境下独自的状态。
2.6 在多屏幕环境下渲染
Rendering in a Multi-Screen Environment
从JDK1.3版本中,Java 2D API就通过配置在本地平台上的设置来支持三种不同的多屏幕配置:
(1) 两到多个独立的屏幕;
(2) 两到多个屏幕,其中一个是主屏幕其他的屏幕是主屏幕的复制;
(3) 两到多个屏幕组成一个虚拟桌面,这也叫做虚拟设备。
Java 2D API使你能通过一个GraphicsConfiguration创建适应目标渲染显示设备的Frame、JFrame、Window、JWindow对象。
在上面三种配置中,每个屏幕设备都有一个GraphicsDevice表示。每一个GraphicsDevice都能有多个GraphicsConfiguration对象和它关联。
当两个或多个屏幕组成一个虚拟设备时,存在于物理屏幕外的虚拟坐标系统用来表示虚拟设备。在这多屏幕配置中,每个GraphicsConfiguration的界限和虚拟坐标系相联系。这种环境下的每个屏幕被定义为首选屏幕,它在虚拟坐标系中定位在(0,0)位置。根据首先屏幕的位置,虚拟设备的坐标系可能是相反的,如下图所示:
在你的系统上,你可以在每个GraphicsConfiguration对象上调用getBounds来检查原点是(0,0)而不是其它位置来检测你的环境是否为虚拟环境,在它上面Window或Frame能跨越一人或多个物理设备。GraphicsConfiguration上的getBounds方法返回在虚拟坐标上的一个矩形区域。所以如果任何设备的原点不是(0,0)那么它们就是虚拟设备环境。
在虚拟设备环境,GraphicsConfiguration对象的坐标是和虚拟的坐标系想联系的。所以当你调用一个Frame或Window的setLocation方法时,你必须使用虚拟坐标。举例来说,下面的代码获得GraphicsConfiguration的界限,并根据这个范围在相对于由这个GraphicsConfiguration表示的物理屏幕原点的(10,10)位置设备了一个Frame:
Frame f = new Frame(GraphicsConfiguration gc);
Rectangle bounds = gc.getBounds();
f.setLocation(10 + bounds.x , 10 + bounds.y);
如果没有把GraphicsConfiguration的界限考虑在内,把这个Frame显示在首先物理屏幕的(10,10)位置,那么它将和指定的GrapihcsConfiguration表示的物理屏幕上显示的不同。
getBounds方法同样可用于限定虚拟设备的界限。在你的系统上的每个GraphicsConfiguration上调用getBounds。为了限定物理设备的边界,你需要高处所有的边界。这种技术正如下面的示例中所用到的:
Rectangle virtualBounds = new Rectangle();
GraphicsEnvironment ge = GrahicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for( int j = 0; j < gs.length; j++){
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc = gd.getConfigurations();
for( int i = 0; i < gc.length; i++){
VirturalBounds = virtualBounds.union(gc[i].getBounds());
}
}
现在的applet中,利用GraphicsEnvironment里的每个GraphicsDevice的GraphicsConfiguration来创建一个JFrame。每个JFrame显示了一组红、绿、蓝条纹的集合,屏幕的数量、GraphiscConfiguration的数量以其GraphicsConfiguration的界限。下面的代码必须在Jdk1.3以后的版本中运行:
import java.applet.Applet;
import java.awt.*;
import javax.swing.*;
public class MultiFrameApplet extends Applet{
public MultiFrameApplet(){
main(null);
}
public static void main(String[] args){
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for(int j = 0; j < gs.length; j++){
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc = gd.getConfigurations();
for ( int i = 0; i < gc.length; i++){
JFrame f = new JFrame(gs[j].getDefaultConfiguration());
GCCanvas c = new GCCanvas(gc[i]);
Rectangle gcBounds = gc[i].getBounds();
int xoffs = gcBounds.x;
int yoffs = gcBounds.y;
f.getContentPane().add(c);
f.setTitle("Screen# "+Integer.toString(j)+", GC# "+Integer.toString(i));
f.setSize(300,150);
f.setLocation((i * 50) + xoffs , (i * 60 ) + yoffs);
f.show();
}
}
}
}
class GCCanvas extends Canvas{
GraphicsConfiguration gc;
Rectangle bounds;
public GCCanvas(GraphicsConfiguration gc){
super(gc);
this.gc = gc;
bounds = gc.getBounds();
}
public Dimension getPreferedSize(){
return new Dimension(300,150);
}
public void paint(Graphics g){
g.setColor(Color.red);
g.fillRect(0 , 0 , 100 , 150 );
g.setColor(Color.green);
g.fillRect(100 , 0 , 100 , 150);
g.setColor(Color.blue);
g.fillRect(200 , 0 , 100 ,150);
g.setColor(Color.black);
g.drawString( "ScreenSize = " + Integer.toString(bounds.width) + " X " + Integer.toString(boudns.height), 10 , 15) ;
g.drawString(gc.toString(), 10 , 30);
}
}
Rendering Graphics Primitives
Graphics2D为图形、文本、图像提供了渲染方法:
(1) draw - 在Graphics2D上下文中通过Stroke和Paint对象描绘图形路径;
(2) fill - 在上下文中使用Paint填充图形;
(3) drawString - 在上下文中使用Paint渲染指定的字符串;
(4) drawImage - 渲染指定图像
为了能描绘并填充图形,你需要调用draw和fill方法。
Graphics2D在先前的JDK版本中同样支持draw和fill方法,例如drawOval和fillRect.
2.4.1 绘制图形
Draw a Shape
图形的轮廓能通过Graphics2D.draw方法来渲染。先前的JDK中支持 的draw方法还有:drawLine、drawRect、drawRoundRect、drawOval、drawAcr、drawPolyline、 drawPolygon和draw2DRect。
当一个图形被绘制,它的路径通过Graphics2D上下文中的Stroke对象来描边。在上下文中通过设置一个合适的BasicStroke对象,你可以绘制任何宽度和样式的线条。BasicStroke同样定义了线条的端部和结合点的属性。
渲染图形的轮廓的步骤:
(1) 创建一个BasicStroke对象;
(2) 调用Graphics2D.setStroke方法;
(3) 创建Shape;
(4) 调用Graphics2D.draw(shape);
下面的示例中,GeneralPath对象用来定义一个五星然后用BasicStroke对象来定义五星的线条和结合点属性:
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g ;
//创建并设置stroke
g2.setStroke(new BasicStroke( 4.0f ));
//使用GeneralPath对象创建一个五星
GeneralPath p = new GeneralPath(GeneralPath.NON_ZERO);
p.moveTo( - 100.0f, -25.0f );
p.lineTo(+100.0f, -25.0f );
p.lineTo( - 50.0f, -25.0f);
p.lineTo( +0.0f, -100.0f);
p.lineTo(+50.0f , +100.0f);
p.closePath();
//translate origin towards center of canvas
g2.translate(100.0f, 100.0f);
//渲染五星的路径
g2.draw(p);
}
2.4.2 填充图形
Filling a Shape
Graphics2D.fill方法可用来填充任何的图形。当填充一个图形时,它的图形路径内部的的区域将被Paint的当前属性——Color、TexturePaint、及GradientPaint渲染。
先前的JDK版本中支持的填充方法有:fillRect、fill2DRect、fillRoundRect fillOval、fillArc、fillPolygon、clearRect。
填充一个图形的基本步骤:
(1) 在上下文中使用Graphics2D.setColor或Graphics2D.setPaint设置填充的颜色和模式;
(2) 创建一个Shape对象;
(3) 调用Graphics2D.fillRect渲染图形对象;
在下面的示例中,调用setColor来为一个Rectangle2D对象定义一个绿色填充:
public void paint(Graphics g){
Graphics2D g2 = (Graphcs2D) g;
g2.setPaint(Color.green);
Rectangle2D r2 = new Rectangle2D.Float(25,25,150,250);
g2.fill(r2);
}
2.4.3 渲染文本
Rendering Text
为了渲染字符串,你可以调用Graphics2D.drawString并把它传递到你要渲染的字符串。关于渲染文本和选择字体的信息,请参见"字体和文本布局(Fonts and Text Layout)"。
2.4.4 渲染图像
Rendering Images
为了渲染图像,你需要创建Image对象,并调用Graphics2D.drawImage.更多关于处理和渲染图片的信息请参见"图形渲染(Imaging)"。
2.5 定义自定义的混合规则
Defining Custom Composition Rules
通过实现Composite和CompositeContext接口,你可以创建一个全新的混合操作类型。一个Composite对象提供的CompositeContext对象实际上保持了混合状态并完成混合工作。可以从Composite中创建多种CompositeContext对象来保持在不同环境下独自的状态。
2.6 在多屏幕环境下渲染
Rendering in a Multi-Screen Environment
从JDK1.3版本中,Java 2D API就通过配置在本地平台上的设置来支持三种不同的多屏幕配置:
(1) 两到多个独立的屏幕;
(2) 两到多个屏幕,其中一个是主屏幕其他的屏幕是主屏幕的复制;
(3) 两到多个屏幕组成一个虚拟桌面,这也叫做虚拟设备。
Java 2D API使你能通过一个GraphicsConfiguration创建适应目标渲染显示设备的Frame、JFrame、Window、JWindow对象。
在上面三种配置中,每个屏幕设备都有一个GraphicsDevice表示。每一个GraphicsDevice都能有多个GraphicsConfiguration对象和它关联。
当两个或多个屏幕组成一个虚拟设备时,存在于物理屏幕外的虚拟坐标系统用来表示虚拟设备。在这多屏幕配置中,每个GraphicsConfiguration的界限和虚拟坐标系相联系。这种环境下的每个屏幕被定义为首选屏幕,它在虚拟坐标系中定位在(0,0)位置。根据首先屏幕的位置,虚拟设备的坐标系可能是相反的,如下图所示:
![](https://img-my.csdn.net/uploads/201206/13/1339601764_7585.jpg)
在虚拟设备环境,GraphicsConfiguration对象的坐标是和虚拟的坐标系想联系的。所以当你调用一个Frame或Window的setLocation方法时,你必须使用虚拟坐标。举例来说,下面的代码获得GraphicsConfiguration的界限,并根据这个范围在相对于由这个GraphicsConfiguration表示的物理屏幕原点的(10,10)位置设备了一个Frame:
Frame f = new Frame(GraphicsConfiguration gc);
Rectangle bounds = gc.getBounds();
f.setLocation(10 + bounds.x , 10 + bounds.y);
如果没有把GraphicsConfiguration的界限考虑在内,把这个Frame显示在首先物理屏幕的(10,10)位置,那么它将和指定的GrapihcsConfiguration表示的物理屏幕上显示的不同。
getBounds方法同样可用于限定虚拟设备的界限。在你的系统上的每个GraphicsConfiguration上调用getBounds。为了限定物理设备的边界,你需要高处所有的边界。这种技术正如下面的示例中所用到的:
Rectangle virtualBounds = new Rectangle();
GraphicsEnvironment ge = GrahicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for( int j = 0; j < gs.length; j++){
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc = gd.getConfigurations();
for( int i = 0; i < gc.length; i++){
VirturalBounds = virtualBounds.union(gc[i].getBounds());
}
}
现在的applet中,利用GraphicsEnvironment里的每个GraphicsDevice的GraphicsConfiguration来创建一个JFrame。每个JFrame显示了一组红、绿、蓝条纹的集合,屏幕的数量、GraphiscConfiguration的数量以其GraphicsConfiguration的界限。下面的代码必须在Jdk1.3以后的版本中运行:
import java.applet.Applet;
import java.awt.*;
import javax.swing.*;
public class MultiFrameApplet extends Applet{
public MultiFrameApplet(){
main(null);
}
public static void main(String[] args){
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for(int j = 0; j < gs.length; j++){
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc = gd.getConfigurations();
for ( int i = 0; i < gc.length; i++){
JFrame f = new JFrame(gs[j].getDefaultConfiguration());
GCCanvas c = new GCCanvas(gc[i]);
Rectangle gcBounds = gc[i].getBounds();
int xoffs = gcBounds.x;
int yoffs = gcBounds.y;
f.getContentPane().add(c);
f.setTitle("Screen# "+Integer.toString(j)+", GC# "+Integer.toString(i));
f.setSize(300,150);
f.setLocation((i * 50) + xoffs , (i * 60 ) + yoffs);
f.show();
}
}
}
}
class GCCanvas extends Canvas{
GraphicsConfiguration gc;
Rectangle bounds;
public GCCanvas(GraphicsConfiguration gc){
super(gc);
this.gc = gc;
bounds = gc.getBounds();
}
public Dimension getPreferedSize(){
return new Dimension(300,150);
}
public void paint(Graphics g){
g.setColor(Color.red);
g.fillRect(0 , 0 , 100 , 150 );
g.setColor(Color.green);
g.fillRect(100 , 0 , 100 , 150);
g.setColor(Color.blue);
g.fillRect(200 , 0 , 100 ,150);
g.setColor(Color.black);
g.drawString( "ScreenSize = " + Integer.toString(bounds.width) + " X " + Integer.toString(boudns.height), 10 , 15) ;
g.drawString(gc.toString(), 10 , 30);
}
}