[英]Dynamic Bar chart in Java FX
Hello I am trying to create bar chart which shows values of field. 您好我正在尝试创建显示字段值的条形图。 Values of field are changed by sorting algorithm and chart should show any of changes.
字段值通过排序算法更改,图表应显示任何更改。
public class FXMLDocumentController implements Initializable {
static int[] pole = new int[10]; // field
int hodnota;
@FXML // bar chart
private BarChart barChart;
@FXML
private void handleButtonAction(ActionEvent ev) { //button for filling up new random graph
for (int i = 0; i < 10; i++) {
hodnota = intValue((StrictMath.random() * 100));
pole[i] = hodnota;
}
final CategoryAxis osaX = new CategoryAxis();
final NumberAxis osaY = new NumberAxis();
ObservableList<XYChart.Series<String, Number>> barChartData = FXCollections.observableArrayList();
final BarChart.Series<String, Number> series1 = new BarChart.Series<>();
series1.getData().add(new XYChart.Data<>("1", pole[0]));
series1.getData().add(new XYChart.Data<>("2", pole[1]));
series1.getData().add(new XYChart.Data<>("3", pole[2]));
series1.getData().add(new XYChart.Data<>("4", pole[3]));
series1.getData().add(new XYChart.Data<>("5", pole[4]));
series1.getData().add(new XYChart.Data<>("6", pole[5]));
series1.getData().add(new XYChart.Data<>("7", pole[6]));
series1.getData().add(new XYChart.Data<>("8", pole[7]));
series1.getData().add(new XYChart.Data<>("9", pole[8]));
series1.getData().add(new XYChart.Data<>("10", pole[9]));
barChartData.add(series1);
barChart.setData(barChartData);
}
@FXML // button which starts sorting algorhitm, it is changing values in field
private void bubbleButton(ActionEvent ev) {
BubbleSort vlakno=new BubbleSort("vypoctoveVlakno");
vlakno.start();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
I already tried to make a new thread which should load data again and again but it didn't work. 我已经尝试创建一个新的线程,它应该反复加载数据,但它不起作用。 Also tried to load them in the FXML controller but the graphics window gets stuck.
还尝试将它们加载到FXML控制器中,但图形窗口卡住了。 I am actually very new to this.
我其实很新。
FXML document, main just loads stage from fxml FXML文档,主要从fxml加载阶段
<AnchorPane id="AnchorPane" prefHeight="487.0" prefWidth="610.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="radicialgoritmy.FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="14.0" layoutY="14.0" onAction="#handleButtonAction" text="Vygeneruj" />
<BarChart fx:id="barChart" animated="false" cache="true" layoutX="30.0" layoutY="188.0" legendVisible="false" prefHeight="292.0" prefWidth="552.0">
<xAxis>
<CategoryAxis fx:id="osaX" side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis fx:id="osaY" side="LEFT" />
</yAxis>
</BarChart>
<Button fx:id="bubble" layoutX="100.0" layoutY="14.0" mnemonicParsing="false" onAction="#bubbleButton" text="BubbleSort" />
Class for sorting Algorithm. 排序算法类。
class BubbleSort extends Thread {
public BubbleSort(final String jmeno) {
super(jmeno);
}
@Override
public void run() {
for (int i = 0; i < pole.length - 1; i++) {
for (int j = 0; j < pole.length - i - 1; j++) {
if (pole[j] < pole[j + 1]) {
final int tmp = pole[j];
pole[j] = pole[j + 1];
pole[j + 1] = tmp;
}
try {
Thread.sleep(250);
} catch (final InterruptedException ex) {
Logger.getLogger(BubbleSort.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
Here is mcve demonstrating a mechanism to couple changing data to a BarChart
. 这是mcve演示将更改数据耦合到
BarChart
的机制。
There are other ways to achieve this "binding", but I tried to keep is simple. 还有其他方法可以实现这种“绑定”,但我试图保持简单。
The bubble sort algorithm is not relevant to the question, not the answer , so it is better left out. 冒泡排序算法与问题无关,而与答案无关,因此最好省略。 An mcve needs to demonstrate the question / answer, and not the application:
mcve需要演示问题/答案,而不是应用程序:
import java.util.Random;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
public class FXMLDocumentController {
@FXML private BarChart barChart;
private ObservableList<XYChart.Series<String, Number>> barChartData;
private ObservableList<DataItem> items;
private Random rnd = new Random();
private static int SIZE = 10;
@FXML
void initialize(){
//an observable collection of DataItem objects, each representing data of one bar
items = FXCollections.observableArrayList(
dataItem -> new Observable[] { dataItem.nameProperty(), dataItem.valueProperty()});
//initialize with random values
for (int i = 0; i < SIZE; i++) {
items.add(new DataItem(String.valueOf(i), rnd.nextInt(100)));
}
}
@FXML
private void handleButtonAction( ActionEvent ev) {
ObservableList<Data<String, Number>> seriesData = new DataConvertor(items).getData();
CategoryAxis osaX = new CategoryAxis();
NumberAxis osaY = new NumberAxis();
barChartData = FXCollections.observableArrayList();
BarChart.Series<String, Number> series1 = new BarChart.Series<>();
series1.setData(seriesData);
barChartData.add(series1);
barChart.setData(barChartData);
}
@FXML
private void bubbleButton( ActionEvent ev) {
BubbleSort vlakno=new BubbleSort(items);
vlakno.start();
}
}
//pojo to represent items of one bar
class DataItem {
private StringProperty name = new SimpleStringProperty(this, "name");
private IntegerProperty value = new SimpleIntegerProperty(this, "value");
public DataItem( String name, int value) {
setName(name);
setValue(value);
}
public StringProperty nameProperty() {
return name;
}
public String getName() {
return this.nameProperty().get();
}
public void setName( String name) {
this.nameProperty().set(name);
}
public IntegerProperty valueProperty() {
return value;
}
public int getValue() {
return this.valueProperty().get();
}
public void setValue( int value) {
this.valueProperty().set(value);
}
}
//simple coupling between items and graph data
class DataConvertor{
ObservableList<DataItem> items;
ObservableList<Data<String, Number>>data;
DataConvertor( ObservableList<DataItem> items) {
super();
this.items = items;
data = FXCollections.observableArrayList();
items.forEach(item -> data.add(new Data<>(item.getName(), item.getValue())));
items.addListener( ( Change<? extends DataItem> arg0 ) -> update());
}
void update() {
for(int i =0; i < data.size(); i++){
Data<String, Number> d = data.get(i);
d.setYValue(items.get(i).getValue());
}
data.clear();
items.forEach(item -> data.add(new Data<>(item.getName(), item.getValue())));
}
ObservableList<Data<String, Number>>getData(){
return data;
}
}
The BubbleSort
class does not really sort. BubbleSort
类并没有真正排序。 It only changes data periodically and randomly: 它只是定期和随机地更改数据:
import java.util.Random;
import javafx.animation.PauseTransition;
import javafx.collections.ObservableList;
import javafx.util.Duration;
class BubbleSort {
private ObservableList<DataItem> items;
private Random rnd = new Random();
private PauseTransition periodicTask;
private static final long CYCLE = 500;
public BubbleSort(final ObservableList<DataItem> items) {
this.items = items;
periodicTask = new PauseTransition(Duration.millis(CYCLE));
periodicTask.setOnFinished((e) -> {
calculateNewValues();
periodicTask.playFromStart();
});
}
private void calculateNewValues() {
for(DataItem d : items){
d.setValue(rnd.nextInt(100));
}
}
void start(){
periodicTask.playFromStart();
}
}
Note that the posted fxml file in not complete. 请注意,发布的fxml文件未完成。 Those two tags are missing:
缺少这两个标签:
</children>
</AnchorPane>
I altered your program just to give you an idea of one way to accomplish this. 我改变了你的程序只是为了让你了解实现这个目标的一种方法。 I used
Timeline
to implement the BubbleSort
. 我使用
Timeline
来实现BubbleSort
。
Main
主要
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* @author sedri
*/
public class RradiciAlgoritmy extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Controller
调节器
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.util.Duration;
import static oracle.jrockit.jfr.events.Bits.intValue;
public class FXMLDocumentController implements Initializable {
Timeline timeline;
static int[] pole = new int[10]; // field
int hodnota;
int ii;
@FXML // bar chart
private BarChart barChart;
@FXML
private void handleButtonAction(ActionEvent ev) { //button for filling up new random graph
for (int i = 0; i < 10; i++) {
hodnota = intValue((StrictMath.random() * 100));
pole[i] = hodnota;
}
final CategoryAxis osaX = new CategoryAxis();
final NumberAxis osaY = new NumberAxis();
ObservableList<XYChart.Series<String, Number>> barChartData = FXCollections.observableArrayList();
final BarChart.Series<String, Number> series1 = new BarChart.Series<>();
series1.getData().add(new XYChart.Data<>("1", pole[0]));
series1.getData().add(new XYChart.Data<>("2", pole[1]));
series1.getData().add(new XYChart.Data<>("3", pole[2]));
series1.getData().add(new XYChart.Data<>("4", pole[3]));
series1.getData().add(new XYChart.Data<>("5", pole[4]));
series1.getData().add(new XYChart.Data<>("6", pole[5]));
series1.getData().add(new XYChart.Data<>("7", pole[6]));
series1.getData().add(new XYChart.Data<>("8", pole[7]));
series1.getData().add(new XYChart.Data<>("9", pole[8]));
series1.getData().add(new XYChart.Data<>("10", pole[9]));
barChartData.add(series1);
barChart.setData(barChartData);
ii = 0;
timeline = new Timeline(new KeyFrame(Duration.seconds(1), (event) -> {
System.out.println(ii + ": " + Arrays.toString(pole));
for (int j = 0; j < pole.length - (ii) - 1; j++) {
if (pole[j] < pole[j + 1]) {
final int tmp = pole[j];
pole[j] = pole[j + 1];
pole[j + 1] = tmp;
}
}
//Create new data and set it to the series
List<XYChart.Data<String, Number>> tempData = new ArrayList();
for(int i = 0; i < pole.length; i++)
{
tempData.add(new XYChart.Data(Integer.toString(i), pole[i]));
}
barChartData.get(0).getData().setAll(tempData);
ii++;
}));
timeline.setCycleCount(pole.length - 1);
}
@FXML // button which starts sorting algorhitm, it is changing values in field
private void bubbleButton(ActionEvent ev) {
timeline.play();
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
FXML
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.chart.BarChart?>
<?import javafx.scene.chart.CategoryAxis?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="487.0" prefWidth="610.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="radicialgoritmy.FXMLDocumentController">
<children>
<Button fx:id="button" layoutX="14.0" layoutY="14.0" onAction="#handleButtonAction" text="Vygeneruj" />
<BarChart fx:id="barChart" animated="false" cache="true" layoutX="30.0" layoutY="188.0" legendVisible="false" prefHeight="292.0" prefWidth="552.0">
<xAxis>
<CategoryAxis fx:id="osaX" side="BOTTOM" />
</xAxis>
<yAxis>
<NumberAxis fx:id="osaY" side="LEFT" />
</yAxis>
</BarChart>
<Button fx:id="bubble" layoutX="100.0" layoutY="14.0" mnemonicParsing="false" onAction="#bubbleButton" text="BubbleSort" />
</children>
</AnchorPane>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.