/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package nl.fontys.sofa.limo.view.graphs;
import java.awt.Component;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.XYChart;
import javafx.util.Duration;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import org.openide.util.Exceptions;
/**
*
* @author nilsh
*/
public class XYChartComponent<T extends AbstractLimoTableModel> {
Class<? extends XYChart> cl;
private final T tableModel;
private final JFXPanel chartFxPanel;
private XYChart chart;
private JPanel parent;
public XYChartComponent(T tableModel, Class<? extends XYChart> cl) {
this.tableModel = tableModel;
chartFxPanel = new JFXPanel();
this.cl = cl;
}
public void updateData() {
chart.setData(tableModel.getXYChartData(cl));
animateChart();
}
public void init(final JPanel parent, final Object constrain, final Axis xAxis, final Axis yAxis) {
Platform.runLater(() -> createChart(xAxis, yAxis));
this.parent = parent;
SwingUtilities.invokeLater(() -> {
parent.add(chartFxPanel, constrain);
});
}
public void remove() {
SwingUtilities.invokeLater(() -> {
parent.remove(chartFxPanel);
});
}
Timeline tl = new Timeline();
private void animateChart() {
chart.setData(null);
chart.setAnimated(false);
final ObservableList<XYChart.Series> tempSet = FXCollections.<XYChart.Series>observableArrayList();
int frameTime = 1000 / (tableModel.getXYChartData(cl).size());
tl.stop();
tl.getKeyFrames().clear();
tl.getKeyFrames().add(
new KeyFrame(Duration.millis(frameTime), (ActionEvent actionEvent) -> {
tempSet.add(tableModel.getXYChartData(cl).get(tempSet.size()));
chart.setData(tempSet);
}));
tl.setCycleCount(tableModel.getXYChartData(cl).size());
tl.play();
}
private void createChart(Axis xAxis, Axis yAxis) {
Constructor<?>[] constructors = cl.getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 3) {
Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes[0] != Axis.class || parameterTypes[1] != Axis.class || parameterTypes[2] != ObservableList.class) {
continue;
} else {
try {
chart = (XYChart) constructor.newInstance(xAxis, yAxis, tableModel.getXYChartData(cl));
animateChart();
break;
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
}
}
}
}
Scene scene = new Scene(chart);
chartFxPanel.setScene(scene);
}
private static class DecimalFormatRenderer extends DefaultTableCellRenderer {
private static final DecimalFormat formatter = new DecimalFormat("#.0");
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
value = formatter.format((Number) value);
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
}