2016-06-29 3 views
0

私は現在、異なる「リフレッシュレート」で印刷したいJFreeChartを描画しています。現時点では、「ワンショット」で印刷できますが、私はそれをdinamically印刷することはできませんでした。リフレッシュレート私はintの値を自分のコードに保存しています。XYラインを更新するJFreeChartは異なるリフレッシュレートでディナム的に

印刷する前に、すべての計算を行ってから印刷します。私が今しようとしているのは、計算中に印刷することです。 1点の価値を得るとすぐに、それを印刷します。

次のように私の計算コードである:

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の終了前for - ループ(のThread.sleepでそれを試してみました()メソッドの終了時にJFreeChartを出力しません繰り返し)。

グラフをダイナミックに印刷するにはどうすればよいですか?値を計算する際にデータセットを更新する必要がありますか?もしそうなら、どうしたらいいですか?

EDIT:私が達成したいと思っている小さな証明可能な例を作成しました。ボタンを押すと、計算が行われるときにグラフが表示されるのではなく、完了したときに表示されます。私はそれが計算後にポイントごとに表示される方法が欲しい。そして、はい、繰り返しごとに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

@copegあなたが正しいです、それは完全な説明ではありません。 私はさまざまなコンポーネントを持つJframeであるメインの.javaクラスを持っています。特定のボタンを押すと計算が始まります。したがって、 'for'ループはJbuttonの' ActionListener'の内部で呼び出されます。 – Nhekas

+0

'forループはボタンの中で呼び出されます.' JButtonのActionListenerの内部を意味しますか? – copeg

答えて

2

スイングはシングルスレッドです - 描画とイベントはイベントディスパッチスレッド(EDT)で発生します。上のあなたのコメントから、あなたが投稿したループはActionListenerの中で呼び出されます - EDTで発生するので、EDTがフリーズするまではUIの変更は起こりません(例えばactionPerformedの終了後)。あなたが与えられた割合でチャート全体をリフレッシュしたい場合は、私は必要に応じて、チャートを更新し、javax.swing.Timerを使用することをお勧めします、私は別の「リフレッシュ速度」

で印刷したい

。あなたは、彼らが利用可能になるとの点でグラフをリフレッシュしたい場合a)は、あなたの計算の実行を検討、

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

:たとえば、1秒に1回の割合でのJButtonのActionListenerのからタイマーを発射します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