2012-03-04 5 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

Чистое, согласованное форматирование кода было бы оценено. –

+0

@AdamMihalcin: Я почистил его код хотя бы немного. Надеюсь, в будущем Крис не будет бросать нам вызов, публикуя сложный код. –

ответ

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); 
    } 

Edit 1
Что касается вашего последнего комментария:

судимого, что для цикла, и это не имеет никакого значения в программу

Моего код выше конечно, не является кодом, который можно вырезать и вставить в вашу программу и, как ожидается, будет работать, а скорее должен рассматриваться только как пример концепции. Для цикла будет работать, если правильно реализована, как это работает для меня много раз, но у вас не работает, так что мы должны исправить реализацию, и для того, чтобы сделать это, нам нужно больше информации:

  • Как вы генерируете свои данные?
  • Используете ли вы таймер Swing для имитации сбора данных в режиме реального времени?
  • Вам нужно будет хранить свои данные, когда вы их собираете, чтобы ваш paintComponent мог перебирать их. Как вы храните свои данные? Это в ArrayList? Можем ли мы увидеть этот код?
  • Как только мы увидим все это, можем ли мы увидеть код , где вы пытаетесь реализовать цикл for для рисования всех точек данных?

Чтобы показать эту новую информацию, вам нужно будет внести изменения в свой вопрос. Если вы сделаете это, пожалуйста, сообщите мне, комментируя этот ответ.

Edit 2
Это более полный пример того, что я описываю, один с функционирующим циклом, который привлекает все масштабируются точками данных. Конечно, ни один из этих кодов не может быть скопирован и вставлен в ваше приложение, но мы надеемся, что содержащиеся в нем понятия могут быть перенесены. Пожалуйста, спросите, выглядит ли что-то запутанным:

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

его сюжеты все точки, которые должны быть удалены последними при добавлении новых –

+0

Я знаю это. Вы должны прокручивать ** все ** точки каждый раз, когда вызывается paintComponent. Либо это, либо использовать фоновое изображение BufferedImage для рисования, а затем отображение в методе 'paintComponent'. –

+0

Я пробовал это для цикла до того, как было заявлено, но без изменений. –

Смежные вопросы