2016-06-29 1 views
0

현재 다른 새로 고침 빈도로 인쇄하려는 JFreeChart을 그리는 중입니다. 현재 나는 "one shot"으로 인쇄 할 수 있지만, 나는 그것을 dinamically 인쇄 할 수 없었다. 새로 고침 속도 내 코드에 int 값이 저장되어 있습니다.XY 선 업데이트 JFreeChart가 서로 다른 새로 고침 빈도로 업데이트

인쇄하기 전에 모든 계산을 수행 한 다음 인쇄합니다. 제가 지금하려고하는 것은 계산하는 동안 인쇄하는 것입니다. 한 점의 가치를 얻고 인쇄하는 등의 작업을합니다.

XYLineChart_AWT chartTemp = new XYLineChart_AWT(); 
int refreshRate = getRefreshRate(); 
for (int i = 0; i<MaxValue;i++) { 
    //calculate values of Array1, Array2 and Array3 
    chart1.setChart(chartTemp.runSimGraph("Title", "XLabel", "YLabel",true, new double[][]{Array1,Array2,Array3})); 
} 

그러나, 이것은 (각 for의 종료 이전에 Thread.sleep() 메소드를 시도 for -loop의 말에 JFreeChart 만 인쇄 않습니다 다음과 같이

내 계산 코드는 되풀이).

어떻게 그래프를 인쇄 할 수 있습니까? 값을 계산할 때 데이터 집합을 업데이트해야합니까? 그렇다면 어떻게 할 수 있습니까?

편집 : 나는 성취하고자하는 것을 증명할 수있는 작은 예를 만들었습니다. 버튼을 누르면 계산이 진행되는 동안 차트가 표시되는 대신 완료되었을 때 차트가 표시됩니다. 나는 그것의 계산 후에 한 점씩 보여줄 수있는 방법을 원한다. 그리고 네, 반복마다 setChart()를 호출하는 것은 너무 비현실적입니다.

코드 : Test1.java

package cenas; 

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTabbedPane; 

import net.miginfocom.swing.MigLayout; 

public class Test1 extends JFrame 
{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    /** 
    * 
    */ 
    private JTabbedPane tabbedBackground; 



    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        Test2 secondFrame = new Test2(); 
        Test1 mainFrame = new Test1(secondFrame); 
        mainFrame.setVisible(true); 
        secondFrame.setVisible(true); 
        secondFrame.setLocationRelativeTo(null); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     // given some values of w & h 
     return new Dimension(1000, 650); 
    } 

    /** 
    * Create the frame. 
    */ 
    public Test1(Test2 secondFrame) { 

     this.setLocationByPlatform(true); 
     setTitle("IMESS Simulator"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setMinimumSize(new Dimension(1000, 650)); 


     tabbedBackground = new JTabbedPane(JTabbedPane.TOP); 
     setContentPane(tabbedBackground); 
     initComponentsandRunSimulator(secondFrame); 
     pack(); 
     //setResizable(false); 

    } 

    private void initComponentsandRunSimulator(Test2 frame2) { 


     JPanel panel1 = new JPanel(); 
     tabbedBackground.addTab("Strategy and Results", null, panel1, null); 
     tabbedBackground.setEnabledAt(0,true); 
     panel1.setLayout(new MigLayout("", "[400.00px,grow]20[300px,grow]20[300.00px,grow]", "[40px,grow 20][][][][][100px,grow]20[20px]20[250.00px,grow]")); 


     JButton myButton = new JButton("Button - Press me"); 
     myButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       frame2.setComponentsLists(100); 
      } 
     }); 

     //Add Simulation Panel to the layout 
     panel1.add(myButton, "cell 1 1 2 5,grow"); 
    } 

} 

Test2.java

package cenas; 

import java.awt.Dimension; 
import java.awt.EventQueue; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTabbedPane; 

import org.jfree.chart.ChartPanel; 


import net.miginfocom.swing.MigLayout; 

public class Test2 extends JFrame{ 


    /** 
    * 
    */ 
    private static final long serialVersionUID = 1L; 
    private JTabbedPane tabbedBackground2; 
    private ChartPanel chart1 = new ChartPanel (null); 
    private int value; 



    @Override 
    public Dimension getPreferredSize() { 
     // given some values of w & h 
     return new Dimension(1000, 650); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        Test2 frame = new Test2(); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public void setComponentsLists(int refreshRate) { 
     this.value=refreshRate; 
     System.out.println("ola"); 
     simulateValues(refreshRate); 
    } 

    public Test2() { 
     setTitle("IMESS Simulator - Decision System"); 
     setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); 
     setLocationRelativeTo(null); 
     setMinimumSize(new Dimension(1000, 650)); 

     tabbedBackground2 = new JTabbedPane(JTabbedPane.TOP); 
     setContentPane(tabbedBackground2); 
     initComponents(); 
     pack(); 
    } 

private void initComponents() { 

     // Panel 
     JPanel panelSimulation = new JPanel(); 
     tabbedBackground2.addTab("Strategy and Results", null, panelSimulation, null); 
     tabbedBackground2.setEnabledAt(0,true); 
     panelSimulation.setLayout(new MigLayout("", "[400.00px,grow]20[300px,grow]20[300.00px,grow]", "[40px,grow 20][][][][][100px,grow]20[20px]20[250.00px,grow]")); 

     chart1.setPopupMenu(null); 
     chart1.setVisible(true); 

     //Add Simulation Panel to the layout 
     panelSimulation.add(chart1, "cell 0 2"); 
    } 

private void simulateValues(int sliderValue) { 



    double[] Array1 = new double[1440]; 
    double[] Array2 = new double[1440]; 
    double[] Array3 = new double[1440]; 
    for(int i = 0; i<1440; i++) { 
     Array1[i]=0; 
     Array2[i]=0; 
     Array3[i]=0; 
    } 

    int peaks = 0; 



    GraphTest chartTemp = new GraphTest(); 


    //Simulation for 24h (1 point per minute) 
    for(int i = 0; i<1440; i++) { 
     //Some calculations 
     if(i!=0) 
      Array1[i]=Array1[i-1]; 

     if (((i>5) && (i<300)) || ((i>400) && (i<700))) 
     { 
      //Increase the energy per minute 
      if((Array1[i]+10)<=50) 
       Array1[i] = Array1[i]+ 10; 

      else { //if we charge at normal rate, it could surpass capacity, so there may be leftovers 
       Array1[i]=27; 

      }  

     } 

     if (peaks==0) { 
      //Check if there is enough energy to supply in the ESS 
      if(Array1[i]>Array2[i]) { 

       Array3[i]=Array2[i]; //usage by the ESS 
       Array2[i]=0; //Visualization purposes - grid does not provide any energy 
       Array1[i]=Array1[i] - Array3[i]; //energy used by ESS 

      } 

     } 

     chart1.setChart(chartTemp.runSimGraph("Title", "xLabel", "yLabel", true, new double[][]{Array1,Array2,Array3})); 
    } 


} 


} 

GraphTest.java은 "긴 포스트"에 대한 사전 및 유감의

package cenas; 

import java.awt.Color; 
import java.awt.Shape; 
import java.awt.geom.Rectangle2D; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.ChartFactory; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.data.xy.XYSeriesCollection; 
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; 



public class GraphTest { 


    public JFreeChart runSimGraph(String chartTitle, String xLabel, String yLabel, boolean legend ,double[][] graphValues) { 


     JFreeChart xylineChart = ChartFactory.createXYLineChart(
      chartTitle, 
      xLabel, 
      yLabel, 
      createSimDataset(graphValues), 
      PlotOrientation.VERTICAL, 
      legend, false, false); 
     final XYPlot plot = xylineChart.getXYPlot(); 

     //Axes (Domain - x , Range - y) 
     NumberAxis domain = (NumberAxis) plot.getDomainAxis(); 
     domain.setRange(0,24); 
     plot.setBackgroundPaint(new Color(240, 240, 240)); 
     XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(false, true); 
     //renderer.setBaseLinesVisible(false); // retira as linhas entre os pontos 
     //renderer.setBaseShapesFilled(false); //apaga o centro das shapes 
     //renderer.setBaseShapesVisible(false); //apaga as shapes 
     Shape teste = new Rectangle2D.Double(-(1.2/2), -(1.2/2), 1.2, 1.2); 
     renderer.setSeriesShape(0, teste); 
     renderer.setSeriesPaint(0, Color.RED); 
     //renderer.setSeriesStroke(0, new BasicStroke(1.0f)); 
     renderer.setSeriesShape(1, teste); 
     renderer.setSeriesPaint(1, Color.BLUE); 
     renderer.setSeriesShape(2, teste); 
     renderer.setSeriesPaint(2, Color.GREEN); 
     plot.setRenderer(renderer); 

     return xylineChart; 
    } 

    private XYDataset createSimDataset(double[][] values) { 

     double[] gridAr=values[0]; 
     double[] essAr=values[1]; 
     double[] availableEnergy=values[2]; 

     final XYSeries temp1 = new XYSeries("1"); 
     final XYSeries temp2 = new XYSeries("2"); 
     final XYSeries temp3 = new XYSeries("3"); 


     for (double i = 0; i < 1440; i++) { 
      temp1.add(i/60, gridAr[(int) i]); 
      temp2.add(i/60, essAr[(int)i]); 
      temp3.add(i/60, availableEnergy[(int) i]); 
     } 
     final XYSeriesCollection dataset = new XYSeriesCollection(); 
     dataset.addSeries(temp1); 
     dataset.addSeries(temp2); 
     dataset.addSeries(temp3); 
     return dataset; 
    } 




} 

감사합니다,

Nhekas

+0

를 업데이트 생성으로'내 calculattion 코드는 같다 이 '계산'코드는 어디에서 호출 되는가? 다른 말로하면, 어떤 맥락인가? 이것은 자체 스레드에 있습니까? EDT에? – copeg

+0

당신이 맞아요 @ 코펙, 완전한 설명은 아니에요. 다양한 구성 요소가있는 Jframe 인 주 .java 클래스가 있습니다. 특정 버튼을 누르면 계산이 시작됩니다. 그러므로'for' 루프는 Jbutton의'ActionListener' 내부에서 호출됩니다. – Nhekas

+0

'for 루프는 버튼 내부에서 호출됩니다. 'JButton의 ActionListener 내부에 있음을 의미합니까? – copeg

답변

2

스윙은 단일 스레드입니다. 페인팅 및 이벤트는 이벤트 발송 스레드 (EDT)에서 발생합니다. 위의 귀하의 의견에서 게시 한 루프는 EDT에서 발생하는 ActionListener 내에서 호출되므로 EDT가 다시 칠하기 전까지는 UI 변경 (예 : 차트 변경)이 발생하지 않습니다 (예 : actionPerformed 종료 후 언젠가). 난 당신이 주어진 속도에 전체 차트를 새로 고칠 경우 다른 "새로 고침 속도"

로 인쇄하고 싶은

, 내가하는 javax.swing.Timer를 사용하여 필요에 따라 차트를 업데이트하는 것이 좋습니다 것입니다 . 예를 들어, 초당 한번의 속도로 JButton의의의 ActionListener에서 타이머를 해고 :

ActionListener buttonListener = new ActionListener(){ 

    @Override 
    public void actionPerformed(ActionEvent e) { 

     javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       //create the arrays 
       chart1.setChart(chartTemp.runSimGraph("Title", "XLabel", "YLabel",true, new double[][]{Array1,Array2,Array3})); 
      } 

     }); 
     timer.start(); 
    } 
}; 
myButton.addActionListener(buttonListener); 

을 당신은 그들이 출시되면 포인트 차트를 새로 고칠 경우)를 고려하여 계산을 수행 그리고 나서 b) 포인트를 XYSeries에 추가하십시오 (EDT에서는 매번 데이터 세트를 다시 생성하는 것과 반대입니다).Adding points to XYSeries dynamically with JfreeChart에서 적응 예 : 게시 된 예에서

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.util.*; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

import org.jfree.chart.*; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYItemRenderer; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 


public class DynamicPlotAddition extends JFrame { 

    private static final String title = "Dynamic Point Addition"; 
    private final Random rand = new Random(); 
    private XYSeries series = new XYSeries("Added"); 

    public DynamicPlotAddition(String s) { 
     super(s); 
     final ChartPanel chartPanel = createDemoPanel(); 
     this.add(chartPanel, BorderLayout.CENTER); 
     Runnable runner = new Runnable(){ 

      @Override 
      public void run() { 
       int total = 1000; 
       int iter = 0; 
       while (iter++ < total){ 
        SwingUtilities.invokeLater(new Runnable(){ 

         @Override 
         public void run() { 
          series.add(rand.nextGaussian(), rand.nextGaussian()); 
         } 

        }); 

        try{Thread.sleep(100);}catch(Exception e){} 
       } 
      } 

     }; 
     new Thread(runner).start(); 
    } 

    private ChartPanel createDemoPanel() { 
     JFreeChart jfreechart = ChartFactory.createScatterPlot(
      title, "X", "Y", createDataset(), 
      PlotOrientation.VERTICAL, true, true, false); 
     XYPlot xyPlot = (XYPlot) jfreechart.getPlot(); 
     xyPlot.setDomainCrosshairVisible(true); 
     xyPlot.setRangeCrosshairVisible(true); 
     XYItemRenderer renderer = xyPlot.getRenderer(); 
     renderer.setSeriesPaint(0, Color.blue); 
     NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); 
     domain.setVerticalTickLabels(true); 
     return new ChartPanel(jfreechart); 
    } 

    private XYDataset createDataset() { 
     XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); 
     xySeriesCollection.addSeries(series); 
     return xySeriesCollection; 
    } 

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

      @Override 
      public void run() { 
       DynamicPlotAddition demo = new DynamicPlotAddition(title); 
       demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       demo.pack(); 
       demo.setLocationRelativeTo(null); 
       demo.setVisible(true); 
      } 
     }); 
    } 
} 

, 당신은 새 스레드에서 simulateValues에 대한 호출을하고, 각 지점 쌍 적절한 시리즈

+0

차트의 업데이트는 EWT에서 수행해야합니다. 따라서 Timer 대신 SwingWorker를 사용하거나 SwingUtilities.invokeLater() 호출 내에서 setChart() 호출을 래핑하십시오. – FredK

+0

@copeg 감사합니다. 그러나이 솔루션은 작동하지 않았습니다. 루프 내에 타이머를 넣으면 완료된 후에 만 ​​actionPerformed 메서드를 수행합니다. 그리고 각 반복마다 차트를 업데이트하고 싶습니다. – Nhekas

+0

@FredK 그 스윙 타이머 .... [사용법] (https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)'스윙 타이머의 작업은 다음에서 수행됩니다. 이벤트 발송 스레드 ' – copeg

관련 문제