【问题标题】:How to handle an event that produces an image when a button is clicked如何处理单击按钮时生成图像的事件
【发布时间】:2020-03-02 10:42:36
【问题描述】:

我正在创建一个允许两个用户玩井字游戏的界面。游戏规则不需要强制执行,当用户点击按钮时,需要出现“X”或“O”。

我已经设置了界面,但是我无法将需要发生的事件连接到按钮。

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;

public class TicTacToe extends Application {
    private GridPane gBox;
    private HBox hbox;

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        //int n = 18;

        //ArrayList<Button> buttons = new ArrayList<>(n);

        Image image = new Image("file:O.png");
        Image image2 = new Image("file:X.png");
    
        ImageView imageView1 = new ImageView(image2);  

        Button button1 = new Button("X");
        Button button2 = new Button("O");
        Button button3 = new Button("X");
        Button button4 = new Button("O");
        Button button5 = new Button("X");
        Button button6 = new Button("O");
        Button button7 = new Button("X");
        Button button8 = new Button("O");
        Button button9 = new Button("X");
        Button button10 = new Button("O");
        Button button11 = new Button("X");
        Button button12 = new Button("O");
        Button button13 = new Button("X");
        Button button14 = new Button("O");
        Button button15 = new Button("X");
        Button button16 = new Button("O");
        Button button17 = new Button("X");
        Button button18 = new Button("O");

        gBox = new GridPane();

        gBox.add(button1, 0,0);
        gBox.add(button2,0,1);
        gBox.add(button3,1,0);
        gBox.add(button4, 1,1);
        gBox.add(button5, 2,0);
        gBox.add(button6,2,1);

        gBox.add(button7, 0, 5);
        gBox.add(button8,0,6);
        gBox.add(button9, 1,5);
        gBox.add(button10,1,6);
        gBox.add(button11, 2,5);
        gBox.add(button12,2,6);

        gBox.add(button13,0,10);
        gBox.add(button14,0,11);
        gBox.add(button15,1,10);
        gBox.add(button16,1,11);
        gBox.add(button17,2,10);
        gBox.add(button18,2,11);

        gBox.setHgap(130);
        gBox.setVgap(10);
        gBox.setPadding(new Insets(10));

        ButtonClickHandler mbh = new ButtonClickHandler();

        button1.setOnAction(mbh);

        Scene scene = new Scene(gBox, 380, 300);

        primaryStage.setScene(scene);
        primaryStage.setTitle("Tic Tac Toe");
        primaryStage.show();

    }
    class ButtonClickHandler implements EventHandler<ActionEvent>{
        @Override
        public void handle(ActionEvent event){
            Image image = new Image("file:O.png");
            ImageView imageView = new ImageView(image);
            HBox hbox = new HBox(imageView);
 
            Button btn = (Button) event.getSource();
            imageView.setImage(image);      
        }
    }    
}

【问题讨论】:

  • 看来你快到了。您只需将包含ImageViewButtonHBox 组合起来。那并处理您有一个 6 x 3 字段而不是 3 x 3 字段的事实,并选择了一种方法来创建/添加使用大量重复代码的按钮。 (祝你好运,再写 17 行,如 button1.setOnAction(mbh);如果我必须写这样的代码,它只会包含这样的一行......)
  • @fabian 我知道它有很多重复的代码,我想你可以把所有的按钮放在一个数组或数组列表中,无论如何你可以告诉我这是怎么做的(或者你会怎么做) :)?
  • 我真的不知道你到底想做什么。 btn.setGraphic(hbox);? Pane parent = (Pane)button.getParent(); GridPane.setRowIndex(hbox, GridPane.getRowIndex(btn)); GridPane.setColumnIndex(hbox, GridPane.getColumnIndex()); parent.getChildren().set(parent.getChildren().indexOf(btn), hbox); ???还有什么?根据您的要求,正确设计模型并可能设计自定义 gui 元素或至少以专用方法创建/设置按钮可能很有用...

标签: java events javafx


【解决方案1】:

以下mre 重现了您所做的事情,避免重复代码,同时为每个按钮添加事件处理程序:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class TicTacToe extends Application {

    private static String[] BUTTONS_TEXT = {"X", "O"};
    private static int ROWS = 6, COLS = 3;

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

        GridPane gBox = new GridPane();
        ButtonClickHandler mbh = new ButtonClickHandler();

        for (int col = 0; col < COLS ; col++){
            for (int row = 0; row < ROWS ; row++){
                Button button = new Button(BUTTONS_TEXT[0]);
                button.setOnAction(mbh);
                gBox.add(button, col, row);
            }
        }

        gBox.setHgap(10);  gBox.setVgap(10);
        gBox.setPadding(new Insets(10));

        Scene scene = new Scene(gBox);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Tic Tac Toe");
        primaryStage.show();
    }

    class ButtonClickHandler implements EventHandler<ActionEvent>{
        @Override
        public void handle(ActionEvent event){
            Button btn = (Button) event.getSource();
            btn.setText(btn.getText().equals(BUTTONS_TEXT[0]) ? BUTTONS_TEXT[1] : BUTTONS_TEXT[0]);
        }
    }

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

当您的基本功能正常工作时,您可以进行下一步并使用按钮图标而不是文本:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class TicTacToe extends Application {

    private static int ROWS = 6, COLS = 3;
    private static String[] BUTTONS_TEXT = {"X", "O"};

    //always use publicly available resources when posting mre
    private static final String[] imageLink = {
            "http://iconsetc.com/icons-watermarks/simple-black/alphanum/alphanum_lowercase-letter-x/alphanum_lowercase-letter-x_simple-black_64x64.png",
            "http://iconsetc.com/icons-watermarks/simple-black/alphanum/alphanum_lowercase-letter-o/alphanum_lowercase-letter-o_simple-black_64x64.png",
    };

    //construct images once
    private static Image[] images=  {new Image(imageLink[0]), new Image(imageLink[1])};

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

        GridPane gBox = new GridPane();

        for (int col = 0; col < COLS ; col++){
            for (int row = 0; row < ROWS ; row++){
                Button button = new Button();
                button.setOnAction(new ButtonClickHandler(BUTTONS_TEXT[0]));
                button.setGraphic(new ImageView(images[0]));
                gBox.add(button, col, row);
            }
        }

        gBox.setHgap(10);  gBox.setVgap(10);
        gBox.setPadding(new Insets(10));

        Scene scene = new Scene(gBox);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Tic Tac Toe");
        primaryStage.show();
    }

    class ButtonClickHandler implements EventHandler<ActionEvent>{

        private String buttonState; //keeps the current state of the button

        ButtonClickHandler(String buttonState){
            this.buttonState = buttonState;
        }

        @Override
        public void handle(ActionEvent event){

            Button btn = (Button) event.getSource();
            if(buttonState.equals(BUTTONS_TEXT[0])){
                btn.setGraphic(new ImageView(imageLink[1]));
                buttonState = BUTTONS_TEXT[1];
            }else{
                btn.setGraphic(new ImageView(imageLink[0]));
                buttonState = BUTTONS_TEXT[0];
            }
        }
    }

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


【讨论】:

  • 感谢@C0der!不完全是我需要的关于通过按钮单击发生的事件的规范。但我可以从那里完成它。非常感谢您花时间向我展示我正在寻找的 mre。将来肯定会有更多问题,您似乎对 JavaFX 掌握得很好。现在我正在研究如何在 stackoverflow 上提出正确的问题。这会及时到来。
  • " 但是我可以从那里完成它" 这就是这个网站的目的。答案旨在帮助您编写自己的代码。我很高兴它有帮助。当您发布新问题时,请给我留言(如您在此处所做的那样用@c0der 标记),我会尽力提供帮助。我可以帮助解决 Java、Swing 和 JavaFx 问题。
  • 酷,你的背景是什么?您目前在软件开发领域吗?
  • 如果你愿意接受,我什至可能会为这个导师付费。 Def 帮助很大。
  • @DanSchmidt 感谢您的好意。在这个网站上,我们都试图自愿帮助和分享我们有限的知识。我希望您从中受益,也希望与他人分享您的知识。
猜你喜欢
  • 2013-07-03
  • 2011-10-16
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多