package javafxmulticolumnchart;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
*
* @web http://java-buddy.blogspot.com/
*/
public class JavaFXMultiColumnChart extends Application {
public class Record{
private SimpleStringProperty fieldDay;
private SimpleDoubleProperty fieldValue1;
private SimpleDoubleProperty fieldValue2;
Record(String fDay, double fValue1, double fValue2){
this.fieldDay = new SimpleStringProperty(fDay);
this.fieldValue1 = new SimpleDoubleProperty(fValue1);
this.fieldValue2 = new SimpleDoubleProperty(fValue2);
}
public String getFieldDay() {
return fieldDay.get();
}
public double getFieldValue1() {
return fieldValue1.get();
}
public double getFieldValue2() {
return fieldValue2.get();
}
public void setFieldDay(String fDay) {
fieldDay.set(fDay);
}
public void setFieldValue1(Double fValue1) {
fieldValue1.set(fValue1);
}
public void setFieldValue2(Double fValue2) {
fieldValue2.set(fValue2);
}
}
class MyList {
ObservableList<Record> dataList;
ObservableList<PieChart.Data> pieChartData1;
ObservableList<XYChart.Data> xyList2;
MyList(){
dataList = FXCollections.observableArrayList();
pieChartData1 = FXCollections.observableArrayList();
xyList2 = FXCollections.observableArrayList();
}
public void add(Record r){
dataList.add(r);
pieChartData1.add(new PieChart.Data(r.getFieldDay(), r.getFieldValue1()));
xyList2.add(new XYChart.Data(r.getFieldDay(), r.getFieldValue2()));
}
public void update1(int pos, Double val){
pieChartData1.set(pos, new PieChart.Data(pieChartData1.get(pos).getName(), val));
}
public void update2(int pos, Double val){
xyList2.set(pos, new XYChart.Data(xyList2.get(pos).getXValue(), val));
}
}
MyList myList;
private TableView<Record> tableView = new TableView<>();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("java-buddy.blogspot.com");
//prepare myList
myList = new MyList();
myList.add(new Record("Sunday", 100, 120));
myList.add(new Record("Monday", 200, 210));
myList.add(new Record("Tuesday", 50, 70));
myList.add(new Record("Wednesday", 75, 50));
myList.add(new Record("Thursday", 110, 120));
myList.add(new Record("Friday", 300, 200));
myList.add(new Record("Saturday", 111, 100));
Group root = new Group();
tableView.setEditable(true);
Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
TableColumn columnDay = new TableColumn("Day");
columnDay.setCellValueFactory(
new PropertyValueFactory<Record,String>("fieldDay"));
columnDay.setMinWidth(60);
TableColumn columnValue1 = new TableColumn("Value 1");
columnValue1.setCellValueFactory(
new PropertyValueFactory<Record,Double>("fieldValue1"));
columnValue1.setMinWidth(60);
TableColumn columnValue2 = new TableColumn("Value 2");
columnValue2.setCellValueFactory(
new PropertyValueFactory<Record,Double>("fieldValue2"));
columnValue2.setMinWidth(60);
//--- Add for Editable Cell of Value field, in Double
columnValue1.setCellFactory(cellFactory);
columnValue1.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
@Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
((Record)t.getTableView().getItems().get(
t.getTablePosition().getRow())).setFieldValue1(t.getNewValue());
int pos = t.getTablePosition().getRow();
myList.update1(pos, t.getNewValue());
}
});
columnValue2.setCellFactory(cellFactory);
columnValue2.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<Record, Double>>() {
@Override public void handle(TableColumn.CellEditEvent<Record, Double> t) {
((Record)t.getTableView()
.getItems()
.get(t.getTablePosition().getRow())).setFieldValue2(t.getNewValue());
int pos = t.getTablePosition().getRow();
myList.update2(pos, t.getNewValue());
}
});
//--- Prepare StackedBarChart
List<String> dayLabels = Arrays.asList(
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday");
final PieChart pieChart1 = new PieChart(myList.pieChartData1);
pieChart1.setPrefWidth(200);
pieChart1.setTitle("Pie Chart 1");
final CategoryAxis xAxis2 = new CategoryAxis();
final NumberAxis yAxis2 = new NumberAxis();
xAxis2.setLabel("Day");
xAxis2.setCategories(FXCollections.<String> observableArrayList(dayLabels));
yAxis2.setLabel("Value 2");
XYChart.Series XYSeries2 = new XYChart.Series(myList.xyList2);
XYSeries2.setName("XYChart.Series 2");
final LineChart<String,Number> lineChart2 =
new LineChart<>(xAxis2,yAxis2);
lineChart2.setTitle("Line Chart 2");
lineChart2.setPrefWidth(250);
lineChart2.getData().add(XYSeries2);
//---
tableView.setItems(myList.dataList);
tableView.getColumns().addAll(columnDay, columnValue1, columnValue2);
tableView.setPrefWidth(200);
HBox hBox = new HBox();
hBox.setSpacing(10);
hBox.getChildren().addAll(tableView, pieChart1, lineChart2);
root.getChildren().add(hBox);
primaryStage.setScene(new Scene(root, 750, 400));
primaryStage.show();
}
class EditingCell extends TableCell<Record, Double> {
private TextField textField;
public EditingCell() {}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.selectAll();
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(String.valueOf(getItem()));
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@Override
public void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()*2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(Double.parseDouble(textField.getText()));
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
}
Saturday, March 2, 2013
JavaFX: Interaction between table and charts
Last article demonstrate "Update StackedBarChart dynamically, with TableView". It's another example to make PieChart and LineChart update dynamically with TableView.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment