Действия просмотра изображений JavaFX - PullRequest
0 голосов
/ 08 сентября 2018

Я пытаюсь создать копию MineSweeper, чтобы сделать это, я пытаюсь настроить некоторые готовые изображения (100x100 пикселей, сделанные в Photoshop) в виде изображения, а затем при щелчке по нему скрыть его (чтобы отобразить число ниже). Без особых сложностей. Просто изображение становится видимым и невидимым. Я нахожу множество проблем и трудностей.

Вероятно, это связано с полным отсутствием знаний о Javafx в целом, но я даже следую инструкциям, пока не могу реализовать эту функцию. Я приложу к этому свой код Main.Java, мой код sample.fxml (хотя он больше не вызывается), а затем изображение, которое я пытаюсь скрыть при нажатии.

Я провел много исследований по этому вопросу (последние пару дней) и не нашел ничего, что решило бы мои проблемы.

Main.java:

package sample;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    ImageView button;
    @Override
    public void start(Stage primaryStage) throws Exception{
        primaryStage.setTitle("MineSweeper XP");
        button = new ImageView();

        button.setOnMouseClicked(new EventHandler<MouseEvent>)(){

            public void handle(MouseEvent event){

            }
        }

        StackPane layout = new StackPane();
        layout.getChildren().add(button);

        Scene scene = new Scene(layout,1000, 1000);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

sample.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0" prefWidth="100.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <ImageView fx:id="button" fitHeight="150.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@../textures/Button_Custom.png" />
         </image>
      </ImageView>
   </children>
</AnchorPane>

«Кнопка», которая будет использоваться для всех ключей MineSweeper

Моя единственная цель в данный момент - создать окно любого размера, в котором я могу поместить кнопку в любом месте, а затем, когда пользователь нажимает эту кнопку, оно исчезает.

1 Ответ

0 голосов
/ 10 сентября 2018

Одним из возможных решений является создание собственного ImageView, который содержит код для щелчков мыши внутри.

Вот пример TileButton класс:

class TileButton extends ImageView {

    public TileButton() {

        // Set parameters for the image
        Image graphic = new Image("minesweeper/tile.png");
        setImage(graphic);
        setFitWidth(24);
        setFitHeight(24);

        // When this button is click, set its visibility to false.
        setOnMouseClicked(e -> {
            setVisible(false);
        });
    }
}

Используя этот пользовательский класс, вся логика «кнопки» содержится внутри самого TileButton.

Теперь вы можете заполнить ваше минное поле GridPane из StackPane контейнеров в каждой ячейке. StackPane позволяет размещать узлы друг над другом. Итак, поместите Label с нужным номером в каждый StackPane, а затем добавьте новый TileButton поверх него.

Ниже приведен пример приложения для демонстрации. Обратите внимание, я не реализую здесь никакой реальной игровой логики, а просто предоставляю пример, который вы можете скопировать / вставить и увидеть в действии. Я также не тратил время на форматирование и стилизацию ImageView, но вы можете использовать CSS, чтобы заставить его работать как стандартная кнопка.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // GridPane to hold the cells
        GridPane gridPane = new GridPane();
        gridPane.setGridLinesVisible(true);
        gridPane.setHgap(2);
        gridPane.setVgap(2);

        // Populate the Gridpane with a 10x10 grid
        int number = 0;
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {

                // Add a new StackPane for each grid cell. The Stackpane will hold a number and the
                // TileButton. When the TileButton is clicked, it disappears, revealing the number below
                StackPane pane = new StackPane();
                pane.getChildren().add(new Label(String.valueOf(number)));
                pane.getChildren().add(new TileButton());

                gridPane.add(pane, j, i);

                // Just increment our sample number
                number++;

            }
        }

        root.getChildren().add(gridPane);
        primaryStage.setScene(new Scene(root));

        primaryStage.show();
    }
}

class TileButton extends ImageView {

    public TileButton() {

        // Set parameters for the image
        Image graphic = new Image("minesweeper/tile.png");
        setImage(graphic);
        setFitWidth(24);
        setFitHeight(24);

        // When this button is click, set its visibility to false.
        setOnMouseClicked(e -> {
            setVisible(false);
        });
    }
}

Пример приложения выше:

Screenshot

Примечание Я не использую FXML для этого, поскольку создание сетки из нескольких пользовательских объектов в Java намного проще, чем FXML.


За предложение Клеопатры , это можно сделать, используя вместо этого пользовательский Button. С новым классом TileButton, представленным ниже, вы можете добавить кнопки в наш цикл, используя gridPane.add(new TileButton(String.valueOf(number)), j, i);:

class TileButton extends Button {

    public TileButton(String text) {

        // Set the button's size
        setPrefSize(24,24);
        setStyle("-fx-padding: 0");

        // Set the graphic to our tile.png image
        setGraphic(new ImageView("sample/done/minesweeper/tile.png"){{
            setFitWidth(24);
            setFitHeight(24);
        }});

        // Set the button to display only our graphic initially
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

        // Set the action to remove the graphic when the button is clicked
        setOnAction(event -> {
            setGraphic(new Label(text));
        });

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...