在java中绘制一个简单的二维图
Posted
技术标签:
【中文标题】在java中绘制一个简单的二维图【英文标题】:Drawing a simple 2D graph in java 【发布时间】:2013-12-25 04:06:54 【问题描述】:我得到了一个下面的 java 代码,它绘制了一个二维图形,其中 x 轴的值为 1,2,3,......20 y 轴的值为 21,14,18........18 该代码完美运行,但唯一的问题是该图没有分别在 x 轴和 y 轴上显示相应的 x 和 y 值。我知道这可能是对代码的一个小补充。但我是 Java 图形的新手,考虑到时间限制,我无法弄清楚在哪里添加相关代码。
/*Sample code */
public class GraphingData extends JPanel
int[] data =
21, 14, 18, 03, 86, 88, 74, 87, 54, 77,
61, 55, 48, 60, 49, 36, 38, 27, 20, 18
;
final int PAD = 20;
protected void paintComponent(Graphics g)
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = getWidth();
int h = getHeight();
// Draw ordinate.
g2.draw(new Line2D.Double(PAD, PAD, PAD, h-PAD));
// Draw abcissa.
g2.draw(new Line2D.Double(PAD, h-PAD, w-PAD, h-PAD));
// Draw labels.
Font font = g2.getFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = font.getLineMetrics("0", frc);
float sh = lm.getAscent() + lm.getDescent();
// Ordinate label.
String s = "Average Byte Value";
float sy = PAD + ((h - 2*PAD) - s.length()*sh)/2 + lm.getAscent();
for(int i = 0; i < s.length(); i++)
String letter = String.valueOf(s.charAt(i));
float sw = (float)font.getStringBounds(letter, frc).getWidth();
float sx = (PAD - sw)/2;
g2.drawString(letter, sx, sy);
sy += sh;
// Abcissa label.
s = "file blocks";
sy = h - PAD + (PAD - sh)/2 + lm.getAscent();
float sw = (float)font.getStringBounds(s, frc).getWidth();
float sx = (w - sw)/2;
g2.drawString(s, sx, sy);
// Draw lines.
double xInc = (double)(w - 2*PAD)/(data.length-1);
double scale = (double)(h - 2*PAD)/getMax();
g2.setPaint(Color.green.darker());
for(int i = 0; i < data.length-1; i++)
double x1 = PAD + i*xInc;
double y1 = h - PAD - scale*data[i];
double x2 = PAD + (i+1)*xInc;
double y2 = h - PAD - scale*data[i+1];
g2.draw(new Line2D.Double(x1, y1, x2, y2));
// Mark data points.
g2.setPaint(Color.red);
for(int i = 0; i < data.length; i++)
double x = PAD + i*xInc;
double y = h - PAD - scale*data[i];
g2.fill(new Ellipse2D.Double(x-2, y-2, 4, 4));
private int getMax()
int max = -Integer.MAX_VALUE;
for(int i = 0; i < data.length; i++)
if(data[i] > max)
max = data[i];
return max;
public static void main(String[] args)
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new GraphingData());
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
【问题讨论】:
"..考虑到时间限制,我无法弄清楚在哪里添加相关代码。"什么'时间限制'? 我的意思是我有一些时间限制来完成java教程并完全理解图形代码,从而弄清楚在哪里添加代码。 也许你应该把这个任务留到你确实有时间的时候。提供免费帮助的人通常希望您有时间参考他们链接的 Java 文档和教程。 我同意你的观点,但正如我已经提到的对 java 图形的新手,我需要时间来参考 java 文档并了解它的基础知识。作为我项目的一部分,我想展示一些很酷的东西我分析的数据图表。我不能像现在问我的项目是否唯一的目的是展示如何使用 java 图形那样要求这个,我的想法是使用在线可用的实用程序来帮助表示我项目的一个方面。 jfreechart 可能是一个不错的选择;基本示例引用here。 【参考方案1】:public void drawGrid(Graphics g)
g.setColor(Color.black);
int rows = model.maxy-model.miny+1;
int cols = model.maxx-model.minx+1;
int colWidth = (getWidth()-paddingFromRight - ylabelWidth)/cols;
int rowHeight = (getHeight()-xlabelHeight-headingHeight)/rows;
int endX = ylabelWidth + cols * colWidth;
int endY = headingHeight + rows*rowHeight;
for (int k = 0; k <= cols; k++)
g.drawLine(ylabelWidth+colWidth*k, headingHeight, ylabelWidth+colWidth*k, endY); //getHeight()-xlabelHeight
for (int k = 0; k <= rows;k++)
g.drawLine(ylabelWidth, headingHeight+rowHeight*k,endX, headingHeight+rowHeight*k);
public void drawLines(Graphics g)
ArrayList<Line> lines = model.getLines();
Random random = new Random(50);
for (int k = 0; k < lines.size(); k++)
g.setColor(new Color(255-50*k, 50*k, 2*50*k));
//g.setColor(Color.red);
drawLine(g, lines.get(k));
public void drawLine(Graphics g, Line line)
ArrayList<Point> points = line.points;
for (int k = 0; k<points.size()-1;k++)
//scale up points
Point p1 = points.get(k);
Point p2 = points.get(k+1);
g.drawLine(scaleUpX(p1.x), scaleUpY(p1.y), scaleUpX(p2.x), scaleUpY(p2.y));
g.fillOval(scaleUpX(p1.x)-5, scaleUpY(p1.y)-5, 10, 10);
Point p1 = points.get(points.size()-1);
g.fillOval(scaleUpX(p1.x)-5, scaleUpY(p1.y)-5, 10, 10);
public int scaleUpX(int x)
int cols = model.maxx-model.minx+1;
int colWidth = (getWidth()-paddingFromRight - ylabelWidth)/cols;
return ylabelWidth+colWidth*x;
public int scaleUpY(int y)
int rows = model.maxy-model.miny+1;
int rowHeight = (getHeight()-xlabelHeight-headingHeight)/(rows);
//int endY = getHeight()-xlabelHeight;
int endY = headingHeight+rows*rowHeight;
return endY - rowHeight*y;
public void drawLabels(Graphics g)
Dimension d = getSize();
//xlabel
g.drawString(model.xlabel, d.width/2, d.height-xlabelHeight/4);
//ylabel
g.drawString(model.ylabel, 0+5, d.height/2);
//xaxis
int rows = model.maxy-model.miny+1;
int cols = model.maxx-model.minx+1;
int colWidth = (getWidth()-paddingFromRight - ylabelWidth)/cols;
int rowHeight = (getHeight()-xlabelHeight-headingHeight)/rows;
for (int k = 0;k<=cols;k++)
g.drawString(String.valueOf(model.minx+k), ylabelWidth+k*colWidth-5, rowHeight*rows+headingHeight+15);
//yaxis
for (int k = 0;k<=rows;k++)
g.drawString(String.valueOf(model.maxy-k+1),ylabelWidth-15,headingHeight+k*rowHeight);
//heading
FontMetrics fm = g.getFontMetrics();
g.setFont(g.getFont().deriveFont((float)25.0));
g.drawString(model.title, d.width/2-fm.stringWidth(model.title), headingHeight/2+headingHeight/4);
【讨论】:
您应该扩展此答案,而不仅仅是发布代码;它如何回答这个问题?你的方法有什么好处/坏处?【参考方案2】:import java.awt.*;
import javax.swing.*;
public class Graph extends JPanel
private static final int UNIT = 20;
protected void paintComponent(Graphics g)
int YP1,YP2;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
int h = getHeight();
int w = getWidth();
// Draw axeX.
g2.draw(new Line2D.Double(0, h/2, w, h/2)); //to make axisX in the middle
// Draw axeY.
g2.draw(new Line2D.Double(w/2,h,w/2,0));//to make axisY in the middle of the panel
//line between P1(0,1) and P2(1,2) to draw function x+1
Point2D P1 = new Point2D.Double(w/2,(h/2)+ UNIT);
Point2D P2 = new Point2D.Double((w/2)+ UNIT,(h/2)+ 2*UNIT); //considering 20 = 1 unit in your syste,
g2.draw(new Line2D.Double(P1,P2));
public static void main(String[] args)
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Graphe());
f.setSize(400,400);
f.setLocation(200,200);
f.setVisible(true);
【讨论】:
以上是关于在java中绘制一个简单的二维图的主要内容,如果未能解决你的问题,请参考以下文章