所以我真的坚持这个,我需要将代码底部的算法输出到JavaFX中,以显示算法是如何工作的,即冒泡排序将较小的条移动到对的前面我遇到的问题是我无法弄清楚如何让我的算法在JavaFX中正确显示。交换减半和随机工作,但我没有工作的部分代码或上部件,所以我仍然在黑暗中,我仍然是Java新手,JavaFX对我来说有点奇怪
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import static javafx.scene.chart.XYChart.*;
import javafx.geometry.Insets;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class hamrickP2 extends Application {
public static void main(String[] args) {
hamrickP2.launch(args);
}
private static final int
BAR_COUNT = 14,
MAX_BAR_HEIGHT = 50;
private static final String
COLOR_ACTIVE = "-fx-bar-fill: #f64",
COLOR_INITIAL = "-fx-bar-fill: #888",
COLOR_FINALIZED = "-fx-bar-fill: #3cf";
private static final int
DELAY_MILLIS = 700;
@Override
public void start(Stage stage) {
stage.setTitle("Sorting Animations");
stage.setWidth(800);
stage.setHeight(600);
final BorderPane pane = new BorderPane();
pane.setPadding(new Insets(10));
final BarChart<String,Number> chart = new BarChart<>(new CategoryAxis(), new NumberAxis(0, MAX_BAR_HEIGHT, 0));
chart.setLegendVisible(false);
chart.getYAxis().setTickLabelsVisible(false);
chart.getYAxis().setOpacity(0);
chart.getXAxis().setTickLabelsVisible(false);
chart.getXAxis().setOpacity(0);
chart.setHorizontalGridLinesVisible(false);
chart.setVerticalGridLinesVisible(false);
bars = new ArrayList<Data<String,Number>>();
final Series<String,Number> data = new Series<>();
chart.getData().add(data);
for (int i = 0; i < BAR_COUNT; i++) {
bars.add(new Data<>(Integer.toString(i+1), 1));
data.getData().add(bars.get(i));
paint(i, COLOR_INITIAL);
}
pane.setCenter(chart);
inputs = new FlowPane();
inputs.setHgap(5);
inputs.setVgap(5);
createButton("Randomize", () -> randomizeAll());
createButton("Swap Halves", () -> swapHalves());
createButton("Reverse ", () -> reverse());
createButton("Selection Sort", () -> selectionSort());
pane.setBottom(inputs);
stage.setScene(new Scene(pane));
stage.show();
Platform.runLater(() -> randomizeAll());
}
private ArrayList<Data<String,Number>> bars;
private FlowPane inputs;
private void createButton(String label, Runnable method) {
final Button test = new Button(label);
test.setOnAction(event -> new Thread(() -> {
Platform.runLater(() -> inputs.setDisable(true));
method.run();
Platform.runLater(() -> inputs.setDisable(false));
}).start());
inputs.getChildren().add(test);
}
// CHART ACCESSORS AND MUTATORS
private void assign(int index, int value) {
bars.get(index).setYValue(value);
}
private int retrieve(int index) {
return (int) bars.get(index).getYValue();
}
// ANIMATION CONTROLS
private void paint(int index, final String style) {
Platform.runLater(() -> {
bars.get(index).getNode().setStyle(style);
});
}
private void paintAll(final String style) {
Platform.runLater(() -> {
for (int i = 0; i < BAR_COUNT; i++) paint(i, style);
});
}
private void delay() {
try {
Thread.sleep(DELAY_MILLIS);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
// ALGORITHMS FOR BUTTONS
private void randomizeAll() {
Random random = new Random();
for (int i = 0; i < BAR_COUNT; i++) {
assign(i, random.nextInt(MAX_BAR_HEIGHT) + 1);
}
}
private void swapHalves() {
final int half = bars.size()/2;
final int offset = bars.size() % 2;
for (int i = 0; i < half; i++) {
final int j = i + half + offset;
paint(i, COLOR_ACTIVE);
paint(j, COLOR_ACTIVE);
int temp = retrieve(i);
assign(i, retrieve(j));
assign(j, temp);
delay();
paint(i, COLOR_FINALIZED);
paint(j, COLOR_FINALIZED);
}
paintAll(COLOR_INITIAL);
}// Start of algorithms
/**
* Reverse algorithm
* @param array
* @return
*/
public void reverse(){
int array [] = new int [BAR_COUNT];
for(int pos = 0; pos < array.length; pos++)
{
int generic = array[pos];
array[pos] = array[array.length - 1 - pos];
array[array.length -1 - pos] = generic;
int temp = array[array.length -1 - pos];
assign(array[pos] , retrieve(array[array.length - 1 - pos]));
assign(temp , generic);
delay();
paint(pos, COLOR_FINALIZED);
paint( temp, COLOR_FINALIZED);
}
paintAll(COLOR_INITIAL);
}
/**
* Selection Sort algorithm
* @param words
*/
public void selectionSort(){
int arr [] = new int [BAR_COUNT];
for (int i = 0; i < arr.length - 1; i++)
{
paint(i, COLOR_ACTIVE);
int index = i;
for (int j = i + 1; j < arr.length; j++)
if (arr[j] < arr[index])
index = j;
int smallerNumber = arr[index];
arr[index] = arr[i];
arr[i] = smallerNumber;
int temp = retrieve(i);
assign(i, retrieve(i));
assign(index, temp);
delay();
paint(i, COLOR_FINALIZED);
paint(index, COLOR_FINALIZED);
}
paintAll(COLOR_INITIAL);
}
/**
* Bubble Sort algorithm
* @param words
*/
public void bubbleSort(){
int array [] = new int [BAR_COUNT];
int temp;
for(int i = 0; i <array.length; i++){
for(int j = 1; j <array.length -i; j++){
if(array[j-1] > array[j]){
temp = array[j -1];
array[j-1] = array[j];
array[j] = temp;
}
}
}
}
/**
* Insertion Sort algorithm
* @param array
*/
public void insertionSort (){
int array [] = new int [BAR_COUNT];
for (int i = 1; i < array.length; i++) {
int temp = array[i];
int j;
for(j = i -1; j>= 0 && temp < array[j]; j--){
array[j +1 ] = array[j];
array[j + 1 ] =temp;
}
paintAll(COLOR_INITIAL);
}
}
}
答案 0 :(得分:0)
我在代码中发现了一些问题。请考虑以下事项:
bars
设为ObservableList并将其用于您的系列。 Series实例将采用此列表并在内部使用它。通过这种方式,您可以观察列表并稍后修改列表,同时图表会自动更新。访问数据就像使用条形图作为列表或从条形图中提取数组一样简单。我做了两个bubblesort版本。一个访问栏作为列表(inplace),一个访问数组(不到位)。我从你的代码中做了一个例子。我删除了一些东西以使其更清晰:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import java.util.List;
import java.util.Random;
import static javafx.scene.chart.XYChart.Data;
import static javafx.scene.chart.XYChart.Series;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
private static final int
BAR_COUNT = 14,
MAX_BAR_HEIGHT = 50;
private static final String
COLOR_ACTIVE = "-fx-bar-fill: #f64",
COLOR_INITIAL = "-fx-bar-fill: #888",
COLOR_FINALIZED = "-fx-bar-fill: #3cf";
private static final int
DELAY_MILLIS = 700;
private ObservableList<Data<String, Number>> bars;
private BarChart<String, Number> chart;
private FlowPane inputs;
@Override
public void start(Stage stage) {
stage.setTitle("Sorting Animations");
stage.setWidth(800);
stage.setHeight(600);
final BorderPane pane = new BorderPane();
pane.setPadding(new Insets(10));
makeChart(pane);
makeButtons(pane);
stage.setScene(new Scene(pane));
stage.show();
randomizeAll();
}
private void makeChart(BorderPane pane) {
chart = new BarChart<>(new CategoryAxis(), new NumberAxis(0, MAX_BAR_HEIGHT, 0));
chart.setLegendVisible(false);
chart.getYAxis().setTickLabelsVisible(false);
chart.getYAxis().setOpacity(0);
chart.getXAxis().setTickLabelsVisible(false);
chart.getXAxis().setOpacity(0);
chart.setHorizontalGridLinesVisible(false);
chart.setVerticalGridLinesVisible(false);
bars = FXCollections.observableArrayList();
chart.getData().add(new Series<>(bars));
for (int i = 0; i < BAR_COUNT; i++) {
Data<String, Number> dataObject = new Data<>(Integer.toString(i + 1), 1);
bars.add(dataObject); // node will be present after this
addPainting(dataObject.getNode(), COLOR_INITIAL); // do this after bars.add
}
pane.setCenter(chart);
}
private void makeButtons(BorderPane pane) {
inputs = new FlowPane();
inputs.setHgap(5);
inputs.setVgap(5);
createButton("Randomize", () -> randomizeAll());
createButton("Bubble Sort 1", () -> bubbleSort1());
createButton("Bubble Sort 2", () -> bubbleSort2());
pane.setBottom(inputs);
}
private void addPainting(Node newNode, String colorInitial) {
if (newNode != null) {
newNode.setStyle(colorInitial);
}
}
private void createButton(String label, Runnable method) {
final Button test = new Button(label);
test.setOnAction(event -> method.run());
inputs.getChildren().add(test);
}
private void randomizeAll() {
Random random = new Random();
for (Data<String, Number> bar : bars) {
bar.setYValue(random.nextInt(MAX_BAR_HEIGHT) + 1);
}
}
/**
* Bubble Sort algorithm
*/
private void bubbleSort1(){
List<Data<String, Number>> list = bars;
double temp;
for(int i = 0; i < list.size(); i++){
for(int j = 1; j < list.size() - i; j++){
if (getValue(list, j - 1) > getValue(list, j)){
temp = getValue(list, j - 1);
list.get(j - 1).setYValue(list.get(j).getYValue());
list.get(j).setYValue(temp);
}
}
}
}
private double getValue(List<Data<String, Number>> list, int index) {
return list.get(index).getYValue().doubleValue();
}
/**
* Bubble Sort algorithm
*/
private void bubbleSort2(){
double[] array = bars.stream().mapToDouble(data -> data.getYValue().doubleValue()).toArray();
double temp;
for(int i = 0; i <array.length; i++){
for(int j = 1; j <array.length -i; j++){
if(array[j-1] > array[j]){
temp = array[j -1];
array[j-1] = array[j];
array[j] = temp;
}
}
}
for (int i = 0; i < array.length; i++) {
bars.get(i).setYValue(array[i]);
}
}
}
更新1 如果您以可观察的方式实现了分配和检索工作,就像您在问题中已经完成的那样工作。
private void assign(int index, int value) {
bars.get(index).setYValue(value);
}
private int retrieve(int index) {
return (int) bars.get(index).getYValue();
}
我以同样的方式做到了;例如看到最后一个for循环的主体。
要为图表设置动画,您必须重写算法,以便每次调用只执行一步,而不是一次排序整个数组。 例如。在第一次交换后,对bubblesort的函数调用返回。
最后一步是初始化一个TimeLine(Timer),每隔t秒调用一步的bubblesort算法。
棘手的部分是如何记住算法的最后一次运行停止的位置以及如何继续运行。