1

[EDIT] Based on this example, I am now able to collect data and display it in a chart. I don't know exactly how to integrate that code that generates the chart into my application.

/** @see http://stackoverflow.com/questions/5048852 */
public class Atol extends ApplicationFrame {

private static final String TITLE = "Dynamic Series";
private static final String START = "Start";
private static final String STOP = "Stop";
private static final float MINMAX = 100;
private static final int COUNT = 2 * 60;
private static final int FAST = 100;
private static final int SLOW = FAST * 5;
private static final Random random = new Random();
private Timer timer;

public Atol(final String title) {
    super(title);
    final DynamicTimeSeriesCollection dataset
            = new DynamicTimeSeriesCollection(1, COUNT, new Second());
    dataset.setTimeBase(new Second(0, 0, 0, 1, 1, 2011));
    dataset.addSeries(gaussianData(), 0, "Gaussian data");
    JFreeChart chart = createChart(dataset);

    final JButton run = new JButton(STOP);
    run.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            String cmd = e.getActionCommand();
            if (STOP.equals(cmd)) {
                timer.stop();
                run.setText(START);
            } else {
                timer.start();
                run.setText(STOP);
            }
        }
    });

    final JComboBox combo = new JComboBox();
    combo.addItem("Fast");
    combo.addItem("Slow");
    combo.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            if ("Fast".equals(combo.getSelectedItem())) {
                timer.setDelay(FAST);
            } else {
                timer.setDelay(SLOW);
            }
        }
    });
   this.add(new ChartPanel(chart), BorderLayout.CENTER);
   JPanel btnPanel = new JPanel(new FlowLayout());
   btnPanel.add(run);
    btnPanel.add(combo);
    this.add(btnPanel, BorderLayout.SOUTH);
    SystemInfo si = new SystemInfo();             //Criando uma nova classe de infos do Sistem
    HardwareAbstractionLayer hal = si.getHardware(); //Infos de Hardware do sistema
    CentralProcessor cpu = hal.getProcessor();      //E as informações da cpu
    long[] oldTricks = cpu.getSystemCpuLoadTicks();

    
    timer = new Timer(FAST, new ActionListener() {
        float cpu() {

            Double stats = cpu.getSystemCpuLoadBetweenTicks(oldTricks);
            //Convertendo o valor de uso da CPU
            stats = stats * 100d;
            double teste = Math.round(stats * 100.0) / 100.0;
            double d = teste;
            float f = (float) d;
            System.out.println(f);
            return f;
        }
        float[] newData = new float[1];

        @Override
        public void actionPerformed(ActionEvent e) {

            newData[0] = cpu();
            dataset.advanceTime();
            dataset.appendData(newData);
        }
    });
}


private float[] gaussianData() {

    float[] a = new float[COUNT];
    for (int i = 0; i < a.length; i++) {
        a[i] = 2;
    }
    return a;
}

private JFreeChart createChart(final XYDataset dataset) {
    final JFreeChart result = ChartFactory.createTimeSeriesChart(
            TITLE, "hh:mm:ss", "milliVolts", dataset, true, true, false);
    final XYPlot plot = result.getXYPlot();
    ValueAxis domain = plot.getDomainAxis();
    domain.setAutoRange(true);
    ValueAxis range = plot.getRangeAxis();
    range.setRange(-MINMAX, MINMAX);
    return result;
}

public void start() {
    timer.start();
}

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

        @Override
        public void run() {
           Atol demo = new Atol(TITLE);
            demo.pack();

            demo.setVisible(true);
            demo.start();
        }
    });
}

}

To my JFrame code (which is in another class):

   private void kButton3ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    // when I click in that button
    
    Atol demo = new Atol ("");       
   chartCPU.add(new ChartPanel(demo)); //Thats the JPanel the chart need to appear and readjust to it size

}

How can I call the chart (JFreeChart chart) in Atol class if the JFreeChart is in one constructor? I didn't get! How can I make it appear in my chartCPU JPanel? (which is one JFrame class called TelaLogin, not the same as the Atol one).

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
BaaDe
  • 77
  • 1
  • 9
  • Several approaches are examined [here](https://stackoverflow.com/q/5048852/230513). – trashgod Dec 04 '20 at 17:12
  • I didnt understand how can I change from random values to my double stats – BaaDe Dec 05 '20 at 01:25
  • Instead of recreating the entire chart, update the dataset by adding the new value & tick. – trashgod Dec 05 '20 at 14:39
  • I tried to change the gaussianData() to update my cpu() but now i can change my values! Could you check my edit and help me please? – BaaDe Dec 05 '20 at 17:13
  • Freezing suggests that you're blocking the [event dispatch thread](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html); try this [approach](https://stackoverflow.com/a/13205322/230513) instead; also, please [edit] your question to include a minimal reproducible example that shows your revised approach; a related question is examined [here](https://stackoverflow.com/q/64842393/230513). – trashgod Dec 05 '20 at 19:26
  • If `getSystemCpuLoadBetweenTicks()` has acceptable latency, try `javax.swing.Timer`, seen [here](https://stackoverflow.com/search?tab=votes&q=user%3a230513%20%5bjfreechart%5d%20javax.swing.Timer). – trashgod Dec 06 '20 at 13:35
  • I did it! Finally did it! But now I cant make it appear in my already existent jpanel! Its always open a new jpanel – BaaDe Dec 07 '20 at 20:46
  • An `org.jfree.chart.ChartPanel`, for [example](https://stackoverflow.com/a/17507061/230513), _is a_ `javax.swing.JPanel` that will add the required listeners for you. Which approach did you use? – trashgod Dec 07 '20 at 22:18
  • I added my cpu() method inside the timer, so in "new data" I called cpu() instead of random numbers! But now i need to put it in my chartCpu JPanel but this code always open a new window How can I just invoke my chart inside a already existent Jpanel in another class? – BaaDe Dec 07 '20 at 22:34
  • `jFrame.add(new ChartPanel(yourChart))` – trashgod Dec 07 '20 at 23:00
  • But my chart (Freechart chart) is in one constructor, how can i invoke it in another class? please check my edit – BaaDe Dec 07 '20 at 23:26
  • Based on your fragment(s), I'm not sure; please [edit] your question to include a [mcve] that shows your revised approach. – trashgod Dec 07 '20 at 23:45
  • Im sorry, i didnt make me clear that's better? – BaaDe Dec 08 '20 at 00:42
  • Ah, I see; you got the data collection and chart working; now you need to integrate the chart into your application. You should be able to refactor the example constructor into a usable factory method; time permitting, I'll look at this. [Earlier](https://stackoverflow.com/revisions/65144032/5), you showed `CardLayout`; I've also used `JTabbedPane`. Your [mcve] should show which you selected. Also, please don't delete the comment citing the example; it's [required](https://stackoverflow.com/help/licensing). – trashgod Dec 08 '20 at 19:43

1 Answers1

1

Your original question asked how to capture CPU data and display it in a chart. Because the relevant method has low latency, it's possible to invoke the method in the action listener of a javax.swing.Timer as shown here and above.

Data access with unpredictable latency may block the event dispatch thread, in which case you should use a SwingWorker instead, as shown here.

To integrate the chart into your application, refactor the example's constructor into a factory method and adopt an approach such as one of these:

  • CardLayout, shown here.

  • JTabbedPane, shown here.

  • JInternalFrame, shown here and here.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045