2012-03-04 82 views
0

我使用一个线程的输出创建线图,这些线程模拟了运行时间为52秒的传入和传出纸币,这将在线图上显示,如下所示,以显示银行平衡超过52秒!图形绘制问题

目前程序运行正常,当我点击开始点得到更新,但每一个新的点放在图上前一个消失。我可以如何保留图上的所有点。

我会假设我将不得不创建2个新的int变量... prevX & prevY。

enter image description here

import java.awt.*; 
import javax.swing.*; 

public class DrawPanel extends JPanel { 

    private static final int X_AXIS_LENGTH = 700; 
    private static final int Y_AXIS_LENGTH = 230; // could be changed 
    private static final int X_AXIS_OFFSET = 200; 
    private static final int Y_AXIS_OFFSET = 85; 
    private static final int PanelHeight = 365; 
    private static final int PanelWidth = 1000; 

    public DrawPanel() { 
     this.setBackground(Color.white); 
     this.setPreferredSize(new Dimension(PanelWidth, PanelHeight)); 
    } 

    public void paintComponent(Graphics g) { 

     int y = ControlPanel.bk1.getBalance(); // balance 
     int x = ControlPanel.bk1.getWeek(); // weeks // 
     int prevX, prevY; 
     int maxX = ContentPanel.controlPanel.getDuration(); 
     int maxY = 100000; 

     int Xleft = 200; 
     int Xright = 900; 
     int Ytop = 50; 
     int Ybottom = 330;// defining axis 

     while (ControlPanel.bk1.getBalance() > maxY) { 
     int i = maxY/4; 
     maxY = maxY + i; 
     } 

     Graphics2D g2 = (Graphics2D) g; 
     super.paintComponent(g2); 
     g2.setColor(Color.BLUE); 

     BasicStroke pen = new BasicStroke(4F); 
     g2.setStroke(pen); 

     g2.drawLine(Xleft, Ytop, Xleft, Ybottom); // set axis 
     g2.drawLine(Xleft, 280, Xright, 280); 

     int i = X_AXIS_OFFSET + (X_AXIS_LENGTH/2); 
     int ii = X_AXIS_OFFSET + (X_AXIS_LENGTH/4); 
     int iii = ((X_AXIS_LENGTH/4)) * 3 + X_AXIS_OFFSET; 
     BasicStroke spaces = new BasicStroke(1F); 
     g2.setStroke(spaces); 
     g2.drawLine(i, 280, i, 300); 
     g2.drawLine(ii, 280, ii, 300); 
     g2.drawLine(iii, 280, iii, 300); 

     g2.setStroke(pen); 

     Font f = new Font("Serif", Font.BOLD, 14); 
     g2.setFont(f); 
     g2.drawString("Account Balance (£)", 35, 200); 
     g2.drawString("Elapsed Time (Weeks)", 475, 340); 

     g2.setColor(Color.BLACK); 
     String maxXDisplay = Integer.toString(maxX); 
     String maxYDisplay = Integer.toString(maxY); 
     g2.drawString(maxYDisplay, 160, 45); 
     g2.drawString(maxXDisplay, 900, 300); 

     // retrieve values from your model for the declared variables 

     // calculate the coords line on the canvas 

     double balance = PanelHeight 
      - ((((double) y/maxY) * Y_AXIS_LENGTH) + Y_AXIS_OFFSET); 
     double weeks = (((double) x/maxX) * X_AXIS_LENGTH) + X_AXIS_OFFSET; 

     int xPos = (int) Math.round(weeks); 
     int yPos = (int) Math.round(balance); // changing back to int to be used 
              // in drawing oval 

     g2.setColor(Color.RED); 
     g.drawOval(xPos, yPos, 2, 2); 

    } 

    public void reDraw() { 
     repaint(); 
    } 

} 
+0

干净,一致的代码格式将不胜感激。 – 2012-03-04 18:30:40

+0

@AdamMihalcin:我已经至少清理了一下他的代码。希望未来Chris不会通过发布难以阅读的代码来挑战我们。 – 2012-03-04 19:16:15

回答

2

你似乎只是想在你的paintComponent方法来绘制一个点:

g.drawOval(xPos, yPos, 2, 2); 

通常你会通过回路环描绘所有的点在这种方法。例如像:

for (int j = 0; j < maxPointCount; j++) { 
    x = someMethodToGetX(j); 
    y = someMethodToGetY(j); 
    double balance = PanelHeight - ((((double) y/maxY) * 
      Y_AXIS_LENGTH) + Y_AXIS_OFFSET); 
    double weeks = (((double) x/maxX) * X_AXIS_LENGTH) + 
      X_AXIS_OFFSET; 

    int xPos = (int) Math.round(weeks); 
    int yPos = (int) Math.round(balance); 

    g2.setColor(Color.RED); 
    g.drawOval(xPos, yPos, 2, 2); 
    } 

编辑1
关于你最近的评论:

Tryed,对循环和它没有什么区别,以上面的程序

我的代码当然不是可以剪切并粘贴到您的程序中并且可以工作的代码,而只是被视为一个概念的例子。一个for循环将工作,如果正确实施,因为它是为我工作了很多次,但你不工作,所以我们必须解决您的实现,而为了做到这一点,我们需要更多的信息:

  • 怎么样你生成你的数据点?
  • 您是否使用Swing Timer来模拟实时数据收集?
  • 您需要在收集数据点时存储数据点,以便您的paintComponent可以对它们进行迭代。你如何存储你的数据点?它在一个ArrayList中吗?我们可以看到这些代码吗?
  • 一旦我们看到这一切,我们可以看到代码您试图实现一个for循环来绘制所有的数据点?

您需要对您的问题进行编辑以显示此新信息。如果你这样做,请通过评论这个答案来通知我。

编辑2
这是什么我描述,用一个for循环,吸引了所有规模的数据点的功能更完整的示例。当然,这些代码都不能复制并粘贴到您的应用中,但希望可以传输包含的概念。请问是否有什么看起来容易混淆:

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
import java.awt.Stroke; 
import java.awt.event.*; 
import java.awt.geom.Point2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.*; 

public class TestShowGraph { 
    private static final int MAX_POINTS = 30; 
    private static final int TIMER_DELAY = 800; 

    private static void createAndShowGui() { 
     ShowGraph showGraphPanel = new ShowGraph(MAX_POINTS); 
     TimerListener timerListener = new TimerListener(MAX_POINTS, showGraphPanel); 

     JFrame frame = new JFrame("TestShowGraph"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(showGraphPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 

     new Timer(TIMER_DELAY, timerListener).start(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class TimerListener implements ActionListener { 
    private static final double EXP_MULTIPLIER = 0.2; 

    // array of points created in constructor to hold data that 
    // will eventually be displayed in real time. 
    // A Swing Timer will copy a point into the pointsList above. 
    private Point2D[] initPoints; 

    private int maxPoints; 
    private int count = 0; 
    private ShowGraph showGraph; 

    public TimerListener(int maxPoints, ShowGraph showGraph) { 
     initPoints = new Point2D[maxPoints]; 
     this.maxPoints = maxPoints; 
     this.showGraph = showGraph; 

     // create all data points that will eventually be 
     // graphed. This is to simulate real-time data collection 
     for (int i = 0; i < initPoints.length; i++) { 
     double x = (double) i/initPoints.length; 
     double y = 1.0 - Math.exp(-1.0 * i * EXP_MULTIPLIER);   
     initPoints[i] = new Point2D.Double(x, y); 
     } 
    } 

    public void actionPerformed(ActionEvent e) { 
     if (count < maxPoints) { 
     // simply push data from initPoints into the list that will 
     // be used to draw the graph 
     showGraph.addPoint(initPoints[count]); 
     count++; 
     } else { 
     // unless we've run out of points. Then simply start over 
     count = 0; 
     showGraph.clearPointsList(); 
     } 

     // repaint so that the GUI will show the points 
     showGraph.repaint(); 
    } 
} 

@SuppressWarnings("serial") 
class ShowGraph extends JPanel { 

    private static final int PREF_W = 800; 
    private static final int PREF_H = 600; 
    private static final int BORDER_GAP = 50; 
    private static final Color AXIS_COLOR = Color.blue; 
    private static final Color POINTS_COLOR = Color.red; 
    private static final Color BACKGRND_COLOR = Color.white; 
    private static final Stroke AXIS_STROKE = new BasicStroke(3f); 
    private static final Stroke POINTS_STROKE = new BasicStroke(2f); 
    private static final double X_SCALE = PREF_W - 2 * BORDER_GAP; 
    private static final double Y_SCALE = PREF_H - 2 * BORDER_GAP; 
    private static final int POINT_RADIUS = 3; 

    // list that the paintComponent method loops through to 
    // draw points 
    private List<Point2D> pointsList = new ArrayList<Point2D>(); 


    public ShowGraph(int maxPoints) { 
     setBackground(BACKGRND_COLOR); 
    } 

    public void addPoint(Point2D point2d) { 
     pointsList.add(point2d); 
    } 

    public void clearPointsList() { 
     pointsList.clear(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     drawAxises(g2); 
     drawPoints(g2); 
    } 

    private void drawAxises(Graphics g2) { 
     // derive a Graphics2D object from the one provided by the 
     // JVM so we can change settings on it without effecting 
     // the Graphics object provided by the JVM 
     Graphics2D g2Axises = (Graphics2D) g2.create(); 
     g2Axises.setStroke(AXIS_STROKE); 
     g2Axises.setColor(AXIS_COLOR); 
     int x1XAxis = BORDER_GAP; 
     int y1XAxis = PREF_H - BORDER_GAP; 
     int x2XAxis = PREF_W - BORDER_GAP; 
     int y2XAxis = PREF_H - BORDER_GAP; 
     g2Axises.drawLine(x1XAxis, y1XAxis, x2XAxis, y2XAxis); 
     int x1YAxis = BORDER_GAP; 
     int y1YAxis = BORDER_GAP; 
     int x2YAxis = BORDER_GAP; 
     int y2YAxis = PREF_H - BORDER_GAP; 
     g2Axises.drawLine(x1YAxis, y1YAxis, x2YAxis, y2YAxis); 
     g2Axises.dispose(); // because we derived this we must dispose it 
    } 

    private void drawPoints(Graphics2D g2) { 
     Graphics2D g2Points = (Graphics2D) g2.create(); 
     g2Points.setStroke(POINTS_STROKE); 
     g2Points.setColor(POINTS_COLOR); 

     for (Point2D p : pointsList) { 
     // p points hold data between 0 and 1 
     // we must scale our points to fit the display 
     // before displaying them 
     int pX = (int)(X_SCALE * p.getX()) + BORDER_GAP; 
     int pY = PREF_H - (int)(Y_SCALE * p.getY()) - BORDER_GAP; 

     // displayed the scaled points 
     int radius = POINT_RADIUS; 
     g2Points.drawOval(pX - radius, pY - radius, 2 * radius, 2 * radius); 
     } 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(PREF_W, PREF_H); 
    } 

} 

好运。

+0

它的地块所有点应该,但删除最后一个新的加入 – 2012-03-04 18:38:59

+0

我知道这一点。每次调用paintComponent时,必须遍历** all **点。或者使用BufferedImage背景图像来绘制,然后在'paintComponent'方法中显示。 – 2012-03-04 18:41:51

+0

我试过这个for循环之前的方式来陈述,但没有改变。 – 2012-03-04 18:54:07