JavaFX按钮的增减事件无法正常工作

问题描述 投票:0回答:2

我正在研究一个编织应用程序,该应用程序计算行并以模式显示行。

我目前遇到的问题是关于计数器以及它如何遍历数字。我需要一个计数器来循环遍历0-3行,然后将自身重置为三行,然后完成增量操作。

但是,当我在减量侧上工作,然后在两个按钮之间来回单击时,计数器会花一点时间到达应有的位置。

例如,当计数器为3时,我按下了minusButton,它将返回0而不是应该的2。如果我正在执行minusButton并切换到plusButton,则计数器返回到0。

我不确定这是哪里出了问题,但是任何帮助都将不胜感激。

这是我的代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;


public class KnittingCounterApp extends Application{
    private String [] stitchNames = {"Blackberry Stitch","Pennant Sticht","Andalusian Stitch"};
    private String [] blackBerryRows = {"*(knit in the front, then back, then front again of the same stich, purl 3), repeat from * until end of the row"
                                       ,"*(purl 3 together, knit 3) repeat from * until the end of the row"
                                       ,"*(purl 3, knit in the front, then back, then front again of the same stitch), repeat from * until end of row"
                                       ,"*(knit 3, purl together 3), repeat until the end of the row"};
    private String [] pennantRows = {"knit"
                                    ,"purl 1, *(knit 1, purl 4) repeat from * until the last stitch, purl 1"
                                    ,"knit 1, *(knit 3, purl 2) repeat from * until the last stitch, knit 1"
                                    ,"knit 1, *(knit 3, purl 2) repeat from * until the last stitch, knit 1"};
    private String [] andalusianRows = {"knit"
                                       ,"purl"
                                       ,"knit 1, purl 1 repeast until the end of the row"
                                       ,"purl"};
    //int rowCounter = 0;

    //private String [] allRows = {blackBerryRows, pennantRows, andalusianRows};

    protected Text text = new Text();


    private ComboBox<String> stitchBox = new ComboBox<>();  

    @Override
    public void start(Stage primaryStage) {

        Label stitchLabel = new Label("Select Stich: ");
        RadioButton blackBerry = new RadioButton("Blackberry");
        RadioButton pennant = new RadioButton("Pennant");
        RadioButton andalusian = new RadioButton("Andalusian");
        blackBerry.setSelected(true);
        ToggleGroup stitchGroup = new ToggleGroup();
        blackBerry.setToggleGroup(stitchGroup);
        pennant.setToggleGroup(stitchGroup);
        andalusian.setToggleGroup(stitchGroup);
        VBox stitchBox = new VBox(stitchLabel, blackBerry, pennant,andalusian);
        stitchBox.setSpacing(10);

        Button plusButton = new Button("+");
        Button minusButton = new Button("-");
        HBox buttons = new HBox(20);
        buttons.getChildren().addAll(plusButton,minusButton);
        Label test = new Label();
        TextArea ta = new TextArea();
        AtomicInteger rowCounter = new AtomicInteger(0);
        plusButton.setOnAction(e->{ if(rowCounter.get() /3 == 1) {
                                        ta.setText(Integer.toString(rowCounter.get()));
                                        rowCounter.getAndSet(0);
                                    } else {
                                        ta.setText(Integer.toString(rowCounter.get()));
                                        rowCounter.updateAndGet(n->n+1);
                                    }
                                    });
        minusButton.setOnAction(e->{if(rowCounter.get() == 0) {
                                        ta.setText(Integer.toString(rowCounter.get()));
                                        rowCounter.getAndSet(3);
                                    } else {
                                        ta.setText(Integer.toString(rowCounter.get()));
                                        rowCounter.updateAndGet(n->n-1);
                                    }
                                   });
        VBox buttonBox = new VBox(10);
        buttonBox.getChildren().addAll(buttons,ta);

        BorderPane pane = new BorderPane();
        pane.setCenter(buttonBox);
        pane.setLeft(stitchBox);


        Scene scene = new Scene(pane, 550, 350);
        primaryStage.setTitle("Knit Baby Blanket Counter");
        primaryStage.setScene(scene);
        primaryStage.show();


    }


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

    }

}
java button javafx increment decrement
2个回答
0
投票

您的问题与AtomicIntegers有关,我知道的很多。我对AtomicIntegers不太满意,但是您可以做的一种替换是将其替换为类中定义的普通整数。然后将setter方法添加到您的int以更新其val。然后正常做所有事情

private int rowC = 0;

        plusButton.setOnAction(actionEvent -> {
            if(rowC == 3){
                ta.setText("" +1);
                updateRow(1);
            }else{
                int n = rowC + 1;
                ta.setText(""+n);
                updateRow(n);
            }
        });
        minusButton.setOnAction(actionEvent -> {
            if(rowC == 1){
                ta.setText("" +3);
                updateRow(3);
            }else if(rowC == 0){ //Added this so that your count doesn't go to -1
                ta.setText("Please start stitching first");
            }else{
                int n = rowC - 1;
                ta.setText("" +n);
                updateRow(n);
            }
        });
    void updateRow(int n){
        rowC = n;
    }

我测试了代码,它可以正常工作。从1-3和3-1开始。


0
投票

您的代码有2个问题

  1. 假设您正在使用AtomicInteger从多个线程进行更新(因为这是此类的目的;您似乎没有这样做),您不是在执行原子操作,即其他线程可以修改在读取值和取决于所写值的值之间的值。
  2. (实际问题:)您在修改值之前正在更新GUI,即,您将始终看到上次修改的结果,而不是当前的结果。使用更新后的值分配给ta.text

以下代码解决了这两个问题,但是为了简单起见,我建议您仅将值存储在字段中:

plusButton.setOnAction(e->{
    ta.setText(Integer.toString(rowCounter.updateAndGet(i -> i >= 3 ? 0 : i+1)));
});
minusButton.setOnAction(e->{
    ta.setText(Integer.toString(rowCounter.updateAndGet(i -> i <= 0 ? 3 : i-1)));
});

带字段的替代:

private int rowCounter = 0;

...

plusButton.setOnAction(e -> {
    rowCounter = (rowCounter+1) % 4; // alternative using modulo here
    ta.setText(Integer.toString(rowCounter));
});
minusButton.setOnAction(e -> {
    rowCounter = (rowCounter + 3) % 4; // alternative using modulo
    ta.setText(Integer.toString(rowCounter));
});
© www.soinside.com 2019 - 2024. All rights reserved.