javafx tableview中的倒数计时器

时间:2015-11-13 01:17:18

标签: java javafx

我很难在javaFX中制作一个倒数计时器。我希望secondenColumn的值用作计时器。例如,当我使用' seconden' = 200添加行时。计时器必须运行200秒(直到0)。我不知道如何开始计时器的代码。这就是我现在所拥有的......

import java.util.regex.Pattern;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.beans.property.IntegerProperty;
import javafx.collections.ListChangeListener.Change;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.util.Duration;

public class RuniteOre extends Application {

    Stage window;
    TableView<Product> table;
    TextField rockInput, worldInput, aantalSpelers;
    int seconden;

    public static void main(String[] args) {
        launch(args);

    }

    @Override
    public void start(Stage primaryStage) throws Exception {





        window = primaryStage;
        window.setTitle("Runite Ore - Calculator");

        //Rock column
        TableColumn<Product, String> rockColumn = new TableColumn<>("Rock");
        rockColumn.setMinWidth(200);
        rockColumn.setCellValueFactory(new PropertyValueFactory<>("rock"));

        //World column
        TableColumn<Product, Integer> worldColumn = new TableColumn<>("World");
        worldColumn.setMinWidth(100);
        worldColumn.setCellValueFactory(new PropertyValueFactory<>("world"));

        //Aantal spelers column
        TableColumn<Product, Integer> aantalSpelersColumn = new TableColumn<>("Aantal Spelers");
        aantalSpelersColumn.setMinWidth(100);
        aantalSpelersColumn.setCellValueFactory(new PropertyValueFactory<>("aantalSpelers"));

        //Seconden column
        //TableColumn<Product, Integer> secondenColumn = new TableColumn<>("Seconden");
        //secondenColumn.setMinWidth(200);
        //secondenColumn.setCellValueFactory(new PropertyValueFactory<>("seconden"));
        TableView<Product> table = new TableView<>();
        TableColumn<Product, Integer> secondenColumn = new TableColumn<>("Seconden");
        table.getColumns().add(secondenColumn);


        secondenColumn.setCellValueFactory(cellData -> cellData.getValue().secondsProperty().asObject());
        table.getItems().addListener((Change<? extends Product> c) -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    for (Product item : c.getAddedSubList()) {
                        int startValue = item.getSeconden() ;
                        Timeline countdown = new Timeline(new KeyFrame(Duration.seconds(1), e -> 
                            item.setSeconden(item.getSeconden() - 1)
                        ));
                        countdown.setCycleCount(startValue);
                        countdown.play();
                    }
                }
            }
        }); 




        //Rock input
        rockInput = new TextField();
        rockInput.setPromptText("Rocks");
        rockInput.setMinWidth(100);

        //World input
        worldInput= new TextField();
        worldInput.setPromptText("World");

        //Aantal spelers input
        aantalSpelers = new TextField();
        aantalSpelers.setPromptText("Aantal Spelers");

        //Button
        Button addButton = new Button("Add");
        addButton.setOnAction(e -> addButtonClicked());
        Button deleteButton = new Button("Delete");
        deleteButton.setOnAction(e -> deleteButtonClicked());



        HBox hBox = new HBox();
        hBox.setPadding(new Insets(10,10,10,10));
        hBox.setSpacing(10);
        hBox.getChildren().addAll(rockInput, worldInput, aantalSpelers, addButton, deleteButton);

        table = new TableView<>();
        table.getColumns().addAll(rockColumn, worldColumn, aantalSpelersColumn,secondenColumn);

        VBox vBox = new VBox();
        vBox.getChildren().addAll(table, hBox);

        Scene scene = new Scene(vBox);
        window.setScene(scene);
        window.show();


    }

    //Add button clicked
    public void addButtonClicked(){
        Product product = new Product();
        product.setRock(rockInput.getText());
        product.setWorld(Integer.parseInt(worldInput.getText()));
        product.setAantalSpelers(Integer.parseInt(aantalSpelers.getText()));
        //TESTBEREKENING seconden=(Integer.parseInt(aantalSpelers.getText())*10);
        seconden=(Integer.parseInt(aantalSpelers.getText())*10);
        product.setSeconden(seconden);

        table.getItems().add(product);
        rockInput.clear();
        worldInput.clear();
        aantalSpelers.clear();
    }

    //Delete button clicked
    public void deleteButtonClicked(){
        ObservableList<Product> productSelected, allProducts;
        allProducts = table.getItems();
        productSelected = table.getSelectionModel().getSelectedItems();

        productSelected.forEach(allProducts::remove);
    }




}

这是Product类的代码:

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
public class Product {

    private String rock;
    private int world;
    private int aantalSpelers;
    //private int seconden;
    private int timer;

    private final IntegerProperty seconden = new SimpleIntegerProperty() ;

    public Product(){
        this.rock = "";
        this.world = 0;
        this.aantalSpelers = 0;
    }

    public Product(String rock, int world, int aantalSpelers){
        this.rock = rock;
        this.world = world;
        this.aantalSpelers = aantalSpelers;
    }

    public String getRock() {
        return rock;
    }

    public void setRock(String rock) {
        this.rock = rock;
    }

    public int getWorld() {
        return world;
    }

    public void setWorld(int world) {
        this.world = world;
    }

    public int getAantalSpelers() {
        return aantalSpelers;
    }

    public void setAantalSpelers(int aantalSpelers) {
        this.aantalSpelers = aantalSpelers;
    }

    public final int getSeconden() {
        return secondsProperty().get();
    }

    public final void setSeconden(int seconden) {
        secondsProperty().set(seconden);
    }

    public int getTimer() {
        return timer;
    }

    public void setTimer(int timer) {
        this.timer = timer;
    }



        public Product(int seconden) {
            setSeconden(seconden);
        }

        public IntegerProperty secondsProperty() {
            return seconden ;
        }

}

1 个答案:

答案 0 :(得分:1)

只需创建一个Timeline,并在每次向表中添加新行时每秒减少一次值:

public void start(Stage primaryStage) throws Exception {

    // existing code...

    // this just needs to be executed before any rows are added to the table:

    table.getItems().addListener((Change<? extends Product> c) -> {
        while (c.next()) {
            if (c.wasAdded()) {
                for (Product p : c.getAddedSubList()) {
                    int startValue = p.getSeconden();
                    Timeline countdown = new Timeline(new KeyFrame(Duration.seconds(1), 
                        e -> p.setSeconden(p.getSeconden() - 1)));
                    countdown.setCycleCount(startValue);
                    countdown.play();
                }
            }
        }
    });

}

这假设您的Product类遵循JavaFX属性模式,即它具有public IntegerProperty secondenProperty() { ... }方法。

这是一个SSCCE:

import java.util.regex.Pattern;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.ListChangeListener.Change;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class CountdownTable extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        TableView<Item> table = new TableView<>();
        TableColumn<Item, Integer> secondsCol = new TableColumn<>("Seconds");
        table.getColumns().add(secondsCol);

        secondsCol.setCellValueFactory(cellData -> cellData.getValue().secondsProperty().asObject());

        table.getItems().addListener((Change<? extends Item> c) -> {
            while (c.next()) {
                if (c.wasAdded()) {
                    for (Item item : c.getAddedSubList()) {
                        int startValue = item.getSeconds() ;
                        Timeline countdown = new Timeline(new KeyFrame(Duration.seconds(1), e -> 
                            item.setSeconds(item.getSeconds() - 1)
                        ));
                        countdown.setCycleCount(startValue);
                        countdown.play();
                    }
                }
            }
        });

        TextField textField = new TextField();
        textField.setPromptText("Type a time in seconds and press enter");
        Pattern integerPattern = Pattern.compile("\\d*");
        TextFormatter<Integer> formatter = new TextFormatter<Integer>( (TextFormatter.Change c) -> {
            String newText = c.getControlNewText();
            if (integerPattern.matcher(newText).matches()) {
                return c ;
            } else {
                return null ;
            }
        });
        textField.setTextFormatter(formatter);

        textField.setOnAction(e -> {
            if (! textField.getText().isEmpty())
            table.getItems().add(new Item(Integer.parseInt(textField.getText())));
            textField.clear();
        });

        BorderPane root = new BorderPane(table, null, null, textField, null);
        primaryStage.setScene(new Scene(root, 600, 600));
        primaryStage.show();
    }

    public static class Item {

        private final IntegerProperty seconds = new SimpleIntegerProperty() ;

        public Item(int seconds) {
            setSeconds(seconds);
        }

        public IntegerProperty secondsProperty() {
            return seconds ;
        }

        public final int getSeconds() {
            return secondsProperty().get();
        }

        public final void setSeconds(int seconds) {
            secondsProperty().set(seconds);
        }
    }

    public static void main(String[] args) { launch(args); }
}