请教JAVA编程高手一个问题,如何在面板上绘图?
用Java绘图一直都吸引着开发人员的注意。传统上,Java开发人员使用java.awt.Graphics或Java2DAPI进行绘图。一些开发人员甚至使用现成的开源工具箱(如JSci)来绘图。但很多时候,您的选择被限定在了AWT或Swing上。为了最大限度地减少对第三方工具箱的依赖,或者为了简化绘图基础,可以考虑使用Draw2D,并编写自己的代码来制图或绘图。
Draw2D简介
Draw2D是一个驻留在SWTComposite之上的轻量级窗口小部件系统。一个Draw2D实例由一个SWTComposite、一个轻量级系统及其内容的图形组成。图形是Draw2D的构建块。关于Draw2DAPI的所有细节,可以从Draw2DDeveloper’sGuide的Eclipse帮助文件中找到。因为本文不打算成为一篇讲述Draw2D的教程,所以,为了简便起见,只要您了解Draw2DAPI可以帮助您在SWTCanvas上进行绘图就足够了。您可以直接使用一些标准的图形,比如Ellipse、Polyline、RectangleFigure和Triangle,或者,您可以扩展它们来创建自己的图形。此外,一些容器图形,如Panel,可以充当所有子图形的总容器。
Draw2D有两个重要的包:org.eclipse.draw2d.geometry和org.eclipse.draw2d.graph,本文中使用了这两个包。org.eclipse.draw2d.geometry包有一些有用的类,比如Rectangle、Point和PointList,这些类都是自我解释的。另一个包org.eclipse.draw2d.graph开发人员使用的可能不是太多。这个包提供了一些重要的类,比如DirectedGraph、Node、Edge、NodeList和EdgeList,这些类有助于创建图表。
在本文中,我将解释如何使用Draw2D编写代码,帮助您以图形的方式形象化您的数据。我将从一项技术的描述开始,该技术将位于某一范围内的数据值(比如,从0到2048)按比例缩放成另一范围内的等效数据值(例如,从0到100)。然后,我将举例说明如何绘制出任意个级数的X-Y坐标图,每个级数都包含一组数据元素。在学习了本文中的概念之后,就可以很容易地绘制其他类型的图表,比如饼图和条形图。
具体的绘图过程
步骤1:您想绘制什么样的图形?
显然,您想以图形方式描绘来自数据源的数据。所以,您需要那些您想以图形形式形象化的数据。为了简便起见,我使用了一个名为dataGenerator的简单函数生成的数据,而不是从XML文件或其他一些数据源读取数据,该函数使用了一个for(;;)循环,并以数组列表的形式返回生成的值。
清单1.生成一些数据
privateArrayListdataGenerator(){
doubleseries1[]=newdouble[5];
for(inti=0;i
series1[i]=(i*10)+10;//alinear
seriescontaining10,20,30,40,50
doubleseries2[]=newdouble[9];
series2[0]=20;series2[1]=150;series2[2]=5;
series2[3]=90;series2[4]=35;series2[5]=20;
series2[6]=150;series2[7]=5;series2[8]=45;
doubleseries3[]=newdouble[7];
for(inti=0;i
series3[i]=(i*20)+15;
seriesData.add(series1);
seriesData.add(series2);
seriesData.add(series3);
returnseriesData;
步骤2:缩放技术——从给定的数据生成X坐标和Y坐标
一些新的术语
FigureCanvas
Draw2D中的FigureCanvas是SWTCanvas的一个扩展。FigureCanvas可以包含Draw2D图形。
Panel
Panel是Draw2D中的一个通用容器图形,它可以包含子图形。您可以向一个Panel图形中添加许多图形,然后将这个Panel图形提供给FigureCanvas。
DirectedGraph
DirectedGraph是一个2-D图形,拥有有限数量的Node,每个Node都位于一些Point中,相邻的Node是通过Edges彼此连接在一起的。
当您想绘制一架2-D飞机上的点时,必须找出每个点的X坐标和Y坐标。绘图的奇妙之处在于能够将某一个给定数据值从一个范围按比例缩放到另一个范围中,也就是说,如果给定一组值,如{10,20,30},那么您应该能够确定2-D飞机上具体哪些点(X坐标和Y坐标)表示的是10、20和30这些数据值。
绘制总是在按照某一个限定缩放比例进行的。换句话说,在同一限定区域内,可以绘制任意数量的点。因为该区域是固定的,所以您总是可以找到X坐标轴的跨度(长度)和Y坐标轴的跨度(高度)。X坐标轴和Y坐标轴的跨度只是等式的一部分。另一部分是找出数据值的范围,并根据每个数据值在新范围内的等效值来计算这些值的坐标。
计算X坐标和Y坐标
X坐标:X坐标是某一个点距离原点的水平距离。计算元素的数量,然后将X坐标轴的跨度分成n个区段,其中,n是给定集合中的元素的数量,通过这种方式,可以计算某一集合中的所有点的横向坐标。用这种分割方法可以获得每个区段的长度。集合中的第一个点位于等于区段长度的第一段距离内。后续的每个点则位于区段长度加上原点到前一个点的距离的那一段距离内。
例如,给出一个集合{10,20,30,40},您立刻就可以知道要绘制4个点,因为集合中包含4个元素。所以,应该将X坐标轴的跨度分成4个相等的区段,每个区段的长度=跨度/4。因此,如果X坐标轴的跨度是800,那么区段的长度将是800/4,即200。第一个元素(10)的X坐标将是200,第二个元素(20)的X坐标将是400,依此类推。
清单2.计算X坐标
privateint[]getXCoordinates(ArrayListseriesData){
intxSpan=(int)GraFixConstants.xSpan;
intlongestSeries=Utilities.getLongestSeries(seriesData);
intnumSegments=
((double[])seriesData.get(longestSeries)).length;
intsectionWidth=
(int)xSpan/numSegments;//wanttodividespanofxAxis
intxPositions[]=
newint[numSegments];//willcontainX-coordinateofalldots.
for(inti=0;i
xPositions[i]=
(i+1)*sectionWidth;//dotsspacedatdistanceofsectionWidth
returnxPositions;
Y坐标:Y坐标是某一个点距离原点的纵向距离。计算Y坐标要将某一个值按比例从一个范围缩放到另一个范围。例如,给出相同的集合{10,20,30,40},您可以看出,数据的范围是0到40,新的范围就是Y坐标轴的跨度(高度)。假设Y坐标轴的高度为400,那么第一个元素(10)的高度将是100,第二个元素的高度将是200,依此类推。
通过以下例子,您可以更好地理解如何按比例将一个值从一个范围缩放到另一个范围:假定一个范围的跨度是从0到2048,而您打算将该范围内的任意值(比如说1024)缩放到另一个从0到100的范围内,那么您立刻就可以知道,等刻度值是50。该缩放所遵循的三值线算法是:
line1--->2048/1024equals2.
line2--->100-0equals100.
line3--->100/2equals50,whichisthedesiredscaLEDvalue.
步骤3:您想在哪儿进行绘图?
您还需要进行绘图的地方。可以通过扩展EclipseViewPart和使用SWTComposite来创建您自己的视图。此外,也可以使用从main()函数中调用的SWTshell。
在扩展EclipseViewPart时,至少必须实现两个函数:createPartControl(Compositeparent)和setFocus()。函数createPartControl(Compositeparent)是在屏幕上绘制视图时自动调用的。您的兴趣只在所接收的SWTComposite上。因此,将它传递给某个类,然后通过对这个类进行编码来绘制图形。
清单3.使用EclipseViewPart绘图
publicclassMainGraFixViewextendsViewPart{
publicvoidcreatePartControl(Compositeparent){
//createorgetdatainanarraylist
ArrayListseriesData=dataGenerator();
//instantiateaplotter,andprovidedatatoit.
DirectedGraphXYPlotterdgXYGraph=newDirectedGraphXYPlotter(parent);
dgXYGraph.setData(seriesData);
dgXYGraph.plot();//askittoplot
publicvoidsetFocus(){
步骤4;您需要绘制哪种图形?
一旦拥有了数据以及想用来绘制图形的区域,就必须确定您需要哪种类型的可视化。在本文中,我演示了如何编写代码来创建X-Y坐标图和线形图。一旦知道了绘制X-Y坐标图的技术,就应该能够绘制出其他图形,比如条形图和饼图。要想更多地了解X-Y坐标图,请参阅我为本文编写的DirectedGraphXYPlotter类(参见所附源代码中的\src\GraFix\Plotters\DirectedGraphXYPlotter.java)。
步骤5:创建自己的X-Y坐标图
X-Y坐标图应该能够绘制出2-D飞机上的任意数量的级数线。每个级数线都应该以图形形式显示出引用X和Y引用线的那些级数中的每个点的位置。每个点都应该通过一条线连接到级数中的下一个点上。通过使用表示一个点和一条线的Draw2D图形,您应该能够创建这样一个坐标图。例如,为了表示一个点,我通过扩展Ellipse图形创建了一个Dot图形,并使用PolylineConnection图形来表示连接线。
DirectedGraphXYPlotter类只有两个公共函数:setData(ArrayListseriesData)和plot()。函数setData(ArrayListseriesData)接受您想要以图形形式形象化的数据(参见步骤1),而plot()函数则开始绘图。
一旦调用了plot()函数,就必须依次采用以下步骤:
采用一个SWTComposite,并将FigureCanvas放在它之上。然后,将一个类似Panel的通用容器图放在画布上。
计算将要绘制的级数的数量,然后填充创建DirectedGraphs所需数量的NodeLists和EdgeLists。
在Panel图上绘制X坐标轴和Y坐标轴。(参见所附源代码中\src\GraFix\Figure目录下的XRulerBar.java和YRulerBar.java。)
创建和级数一样多的DirectedGraphs,以便进行绘图。
在Panel图上绘制点和连接线,同时采用步骤d中创建的DirectedGraphs中的图形数据。
最后,通过提供Panel图来设置画布的内容,其中包括到目前为止您已经准备好的所有的点和连接线。
在以下代码中:
第6-11行代码对应于上述的步骤a。
第14行,即函数populateNodesAndEdges(),对应于上述的步骤b。
第16行,即函数drawAxis(),对应于上述的步骤c。
第17行、第18行和第19行对应于上述的步骤d和步骤e。
第20行对应于上述的步骤f。
清单4.plot()函数
1.publicvoidplot(){
2.//ifnoplacetoplot,ornodatatoplot,return.
3.if(null==_parent||null==_seriesData)
4.return;
6.Compositecomposite=newComposite(_parent,SWT.BORDER);
7.composite.setLayout(newFillLayout());
8.FigureCanvascanvas=newFigureCanvas(composite);
10.Panelcontents=newPanel();//APanelisageneralpurposecontainerfigure
11.contents.setLayoutManager(newXYLayout());
12.initializeSpan(contents.getClientArea());
14.populateNodesAndEdges();
16.drawAxis(contents);
17.for(inti=0;i<_numSeries;i++){
18.drawDotsAndConnections(contents,getDirectedGraph(i));//
drawpoints&connectingwires
20.canvas.setContents(contents);
plot()调用了两个重要内部函数来帮助绘制图形中的点:populateNodesAndEdges()和drawDotsAndConnections()。在您发现这两个函数到底完成什么功能之前,让我们来看一下DirectedGraph。
DirectedGraph是什么?为了使用Draw2D进行绘图,事实上您必须先创建一个图形,定义将要绘制的点和线。一旦创建好这个图形,就可以使用它实际在画布上进行绘图。您可以将DirectedGraph形象化为拥有有限数量的Node的一个2-D图形,在该图形中,每个Node都位于一些Point上,相邻的Node是通过Edges连接在一起的。
您可以通过以下代码行来了解创建DirectedGraph的关键所在。首先,创建一个Node列表和一个Edges列表。然后,创建一个新的DirectedGraph,并通过刚才创建的NodeList和EdgeList设置其成员(Nodes和Edges)。现在,使用GraphVisitor来访问这个DirectedGraph。为了简便起见,包org.eclipse.draw2d.internal.graph中有许多GraphVisitor实现,这些GraphVisitor有一些用来访问图形的特定算法。
因此,创建DirectedGraph的示例代码类似于下面这样:
清单5.示例DirectedGraph
//Thisisasample,youwillneedtoaddactualNode(s)tothisNodeList.
NodeListnodes=newNodeList();//createalistofnodes.
//Thisisasample,youwillneedtoaddactualEdge(s)tothisEdgeList.
EdgeListedges=newEdgeList();//createalistofedges.
DirectedGraphgraph=newDirectedGraph();
graph.nodes=nodes;
graph.edges=edges;
newBreakCycles().visit(graph);//askBreakCyclestovisitthegraph.
//nowour"graph"isreadytobeused.
现在,已经知道DirectedGraph包含许多Node,其中,每个Node都可能包含一些数据,并且还存储了这些数据的X坐标和Y坐标,以及一个Edges的列表,每个Edge都知道在自己的两端分别有一个Node,您可以通过以下技术,使用这些信息来绘图,其中涉及两个部分:部分A——通过以下步骤填充Node和Edge:
创建一个NodeList,在该列表中,集合中的每个元素都有一个Node,集合{10,20,30,40}需要4个Node。
找出每个元素的X坐标和Y坐标,将它们存储在node.x和node.y成员变量中。
创建一个EdgeList,在该列表中,有n-1个Edge,其中,n是集合中的元素的数量。例如,集合{10,20,30,40}需要三个Edge。
将Node与每个Edge的左右端相关联,并相应地设置edge.start和edge.end成员变量。
部分B——通过以下步骤绘制表示Node和Edge的图形:
绘制一个Dot图来表示每个Node。
绘制一个PolylineConnection图形来表示每个Edge。
界定每个PolylineConnection图形,以固定Dot图的左右端。
现在,回到内部函数的工作上来:
函数populateNodesAndEdges()实现了该技术的部分A,而函数drawDotsAndConnections()则实现了该技术的部分B。
函数populateNodesAndEdges()计算将绘制多少级数。它为每个级数创建了一个NodeList和一个EdgeList。
每个NodeList都包含一个用于特殊级数的Node的列表。每个Node都保存着关于应该在什么地方绘制X坐标和Y坐标的信息。函数getXCoordinates()和getYCoordinates()分别用于检索X坐标值和Y坐标值。使用步骤2中的相同算法,这些函数也可以内部地将数据值按比例从一个范围缩放到另一个范围。
每个EdgeList都包含一个用于特殊级数的Edges的列表。每个Edge的左右端上都分别有一个Node。
清单6.populateNodesAndEdges()函数
privatevoidpopulateNodesAndEdges(){
_seriesScaledValues=newArrayList(getScaledValues(_seriesData));
_nodeLists=newArrayList();
_edgeLists=newArrayList();
for(inti=0;i<_numSeries;i++){
_nodeLists.add(newNodeList());//oneNodeListperseries.
_edgeLists.add(newEdgeList());//oneEdgeListperseries.
//populateallNodeListswiththeNodes.
for(inti=0;i<_numSeries;i++){//foreachseries
doubledata[]=(double[])_seriesData.get(i);//gettheseries
intxCoOrds[]=getXCoordinates(_seriesData);
intyCoOrds[]=getYCoordinates(i,data);
//eachNodeListhasasmanyNodesaspointsinaseries
for(intj=0;j
DoubledoubleValue=newDouble(data[j]);
Nodenode=newNode(doubleValue);
node.x=xCoOrds[j];
node.y=yCoOrds[j];
((NodeList)_nodeLists.get(i)).add(node);
//populateallEdgeListswiththeEdges.
for(inti=0;i<_numSeries;i++){
NodeListnodes=(NodeList)_nodeLists.get(i);
for(intj=0;j
NodeleftNode=nodes.getNode(j);
NoderightNode=nodes.getNode(j+1);
Edgeedge=newEdge(leftNode,rightNode);
edge.start=newPoint(leftNode.x,leftNode.y);
edge.end=newPoint(rightNode.x,rightNode.y);
((EdgeList)_edgeLists.get(i)).add(edge);
intbreakpoint=0;
一旦函数populateNodesAndEdges()完成了它的使命,为所有将要绘制的级数创建了NodeLists和EdgeLists,另一个函数drawDotsAndConnections()就开始为每个Node绘制一个Dot图形,并为每个Edge绘制一个PolylineConnection图形。
清单7.drawDotsAndConnections()、drawNode()和drawEdge()函数
privatevoiddrawDotsAndConnections(IFigurecontents,DirectedGraphgraph){
for(inti=0;i
Nodenode=graph.nodes.getNode(i);
drawNode(contents,node);
for(inti=0;i
Edgeedge=graph.edges.getEdge(i);
drawEdge(contents,edge);
privatevoiddrawNode(IFigurecontents,Nodenode){
DotdotFigure=newDot();
node.data=dotFigure;
intxPos=node.x;
intyPos=node.y;
contents.add(dotFigure);
contents.setConstraint(dotFigure,newRectangle(xPos,yPos,-1,-1));
privatevoiddrawEdge(IFigurecontents,Edgeedge){
PolylineConnectionwireFigure=newPolylineConnection();
//edge.sourceistheNodetotheleftofthisedge
EllipseAnchorsourceAnchor=newEllipseAnchor((Dot)edge.source.data);
//edge.targetistheNodetotherightofthisedge
EllipseAnchortargetAnchor=newEllipseAnchor((Dot)edge.target.data);
wireFigure.setSourceAnchor(sourceAnchor);
wireFigure.setTargetAnchor(targetAnchor);
contents.add(wireFigure);
如果您想以图形形式描绘将展示的数据,那么Draw2D是一个好工具。可以使用Draw2D编写自己的用来绘制图形的Java代码,这有助于您将精力集中于缩放代码和绘制代码上,把其他与绘制相关的工作留给Draw2D和SWT。您还可以通过使用所选择的Draw2D图形来控制您的图形的外观。Draw2D简化了绘图的基本步骤,并且可以最大限度地减少您对第三方工具箱的依赖。
参考资料:
关于UG编程的详细步骤!
3D图形的编修(比如说面的修剪、建立毛坯等)----进入加工模块----建立加工坐标系----建立并生成刀路,如粗加工、二次开粗、半精加工、精加工、清角、清边----干涉检查---后处理生成机床识别的文件。
至于你说粗加工多少量,这些个参数,不同的材料、不同的刀具、不同的机床等,都是不同的,这些参数是要经过实际的验证才能确定的,比如说铝的就可以每刀切削深度大点,但是钢的就必须小点。
这种参数,你得自己去试验,就算别人告诉你,也是没多少用,更何况这种东西一般的公司都是做为公司重要技术参数的。当然也不是说完全拿不到。
怎样画出编程图?
用visio或一些软件画出流程图
计算机编程语言是用电脑绘图怎么绘?
计算机语言通常是一个能完整、准确和规则地表达人们的意图,并用以指挥或控制计算机工作的“符号系统”。计算机语言通常分为三类:即机器语言,汇编语言和高级语言。望采纳