JavaFX imageview操作 [英] JavaFX imageview actions

查看:274
本文介绍了JavaFX imageview操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建MineSweeper的副本,为此我尝试将一些预制图像(在Photoshop中制作的100x100像素)设置为imageview,然后单击隐藏它(以显示下面的数字)。没有太多的复杂性 - 只是图像变得可见和不可见我发现了许多问题和困难。



这可能是由于对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;

公共类Main扩展Application {

ImageView按钮;
@Override
public void start(Stage primaryStage)抛出异常{
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);

场景场景=新场景(布局,1000,1000);
primaryStage.setScene(scene);
primaryStage.show();
}

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

sample.fxml:

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

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

< AnchorPane maxHeight = - InfinitymaxWidth = - InfinityminHeight = - InfinityminWidth = - InfinityprefHeight =100.0prefWidth =100.0xmlns =http: //javafx.com/javafx/8.0.121xmlns:fx =http://javafx.com/fxml/1>
< children>
< ImageView fx:id =buttonfitHeight =150.0fitWidth =100.0pickOnBounds =truepreserveRatio =true>
< image>
< Image url =@ .. / textures / Button_Custom.png/>
< / image>
< / ImageView>
< / children>
< / AnchorPane>


注意我没有使用 FXML ,因为在Java中创建多个自定义对象的网格要比FXML简单得多。







kleopatra的建议,这可以使用自定义按钮相反。使用下面的新 TileButton 类,您可以使用 gridPane.add(new TileButton(String.valueOf(number))在循环中添加按钮, j,i);

  class TileButton extends Button {

public TileButton(String text){

//设置按钮的大小
setPrefSize(24,24);
setStyle( - fx-padding:0);

//将图形设置为我们的tile.png图像
setGraphic(new ImageView(sample / done / minesweeper / tile.png){{
setFitWidth(24) ;
setFitHeight(24);
}});

//设置按钮最初只显示我们的图形
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

//设置单击按钮时删除图形的操作
setOnAction(event - > {
setGraphic(new Label(text));
});

}
}


I'm trying to build a replica of MineSweeper, to do this I'm trying to setup some premade images (100x100 pixels made in Photoshop) into an imageview and then when clicked hiding it (to reveal the number below). Without much complexity -- Just the image going visible and invisible I am finding a lot of issues and difficulties.

It is likely due to a complete lack of knowledge on Javafx in general but I even following tutorials to the t I am still unable to implement this feature. I will attach to this my Main.Java code, my sample.fxml code (although it's not called anymore), and then the image I'm trying to hide when clicked.

I have done a lot of research on this (past couple of days) and haven't found anything that solves my problems.

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>

The "Button" that will be used for all the MineSweeper keys

My singular goal at this given moment is to create a window of any size where I can put the button anywhere and then when the user clicks that button it disappears.

解决方案

One possible solution is to create your own ImageView that holds the code for mouse clicks within.

Here's a sample TileButton class:

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);
        });
    }
}

Using this custom class, all the logic for the "button" is contained within the TileButton itself.

Now, you can populate your mine field with a GridPane of StackPane containers in each cell. The StackPane allows you to stack nodes on top of each other. So, place a Label with the number you want into each StackPane and then add your new TileButton on top of it.

Below is a complete sample application to demonstrate. Note, I am not implementing any of the actual game logic here, just providing a sample you can copy/paste and see in action. I also have not spent any time formatting and styling the ImageView, but your could use CSS to make it act like a standard button as well.

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);
        });
    }
}

The above sample application produces this:

Note I am not using FXML for this as creating a grid of multiple custom objects is much simpler in Java than FXML.


Per kleopatra's suggestion, this can be accomplished using a custom Button instead. With the new TileButton class below, you can add the buttons in our loop using 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));
        });

    }
}

这篇关于JavaFX imageview操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆