简体   繁体   中英

JavaFX button doesn't work

This is my first project in Java and JavaFX. I have most of the work done but I need a button that does something. I used things found in different tutorials but my button still doesn't work. Nothing happens when I click it. I will be VERY thankful for any tips. Please find a picture of my application attached so that you can understand better what the code draws. 在此处输入图片说明 Here is my code (button is called b1):

    /*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package po_javafx;

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import static javafx.scene.paint.Color.CORNSILK;
import static javafx.scene.paint.Color.DARKGOLDENROD;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineBuilder;
import javafx.stage.Stage;
import javafx.util.Duration;


public class PO_JavaFX extends Application {

    public static World world = new World("Game");

    static protected int width;
    static protected int height;
    static protected int civilOffsetX;
    static protected int civilOffsetY;
    static protected int bossOffsetX;
    static protected int bossOffsetY;
    static protected int heroOffsetX;
    static protected int heroOffsetY;

    /**
     * @return the civilOffsetX
     */
    public static int getCivilOffsetX() {
        return civilOffsetX;
    }

    /**
     * @param aCivilOffsetX the civilOffsetX to set
     */
    public static void setCivilOffsetX(int aCivilOffsetX) {
        civilOffsetX = aCivilOffsetX;
    }

    /**
     * @return the civilOffsetY
     */
    public static int getCivilOffsetY() {
        return civilOffsetY;
    }

    /**
     * @param aCivilOffsetY the civilOffsetY to set
     */
    public static void setCivilOffsetY(int aCivilOffsetY) {
        civilOffsetY = aCivilOffsetY;
    }

    /**
     * @return the bossOffsetX
     */
    public static int getBossOffsetX() {
        return bossOffsetX;
    }

    /**
     * @param aBossOffsetX the bossOffsetX to set
     */
    public static void setBossOffsetX(int aBossOffsetX) {
        bossOffsetX = aBossOffsetX;
    }

    /**
     * @return the bossOffsetY
     */
    public static int getBossOffsetY() {
        return bossOffsetY;
    }

    /**
     * @param aBossOffsetY the bossOffsetY to set
     */
    public static void setBossOffsetY(int aBossOffsetY) {
        bossOffsetY = aBossOffsetY;
    }

    /**
     * @return the heroOffsetX
     */
    public static int getHeroOffsetX() {
        return heroOffsetX;
    }

    /**
     * @param aHeroOffsetX the heroOffsetX to set
     */
    public static void setHeroOffsetX(int aHeroOffsetX) {
        heroOffsetX = aHeroOffsetX;
    }

    /**
     * @return the heroOffsetY
     */
    public static int getHeroOffsetY() {
        return heroOffsetY;
    }

    /**
     * @param aHeroOffsetY the heroOffsetY to set
     */
    public static void setHeroOffsetY(int aHeroOffsetY) {
        heroOffsetY = aHeroOffsetY;
    }

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

        Pane root = new Pane();
        setWidth(1400);
        setHeight(1000);
        Canvas background = new Canvas(getWidth(), getHeight());

        final GraphicsContext context = background.getGraphicsContext2D();
        File f = new File("background.png");
        final Image image = new Image(new FileInputStream(f));

        root.getChildren().add(background);

        Button b1 = new Button("Spawn Civilian");

        b1.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });
        root.getChildren().add(b1);
        b1.setLayoutX(1300);
        b1.setLayoutY(10);

        Canvas animation = new Canvas(getWidth(), getHeight());
        Canvas animation2 = new Canvas(getWidth(), getHeight());
        final GraphicsContext context2 = animation.getGraphicsContext2D();
        final GraphicsContext context3 = animation2.getGraphicsContext2D();

        File overlay100 = new File("close.png");
        final Image but1;
        but1 = new Image(new FileInputStream(overlay100));

        File overlay = new File("cywil.png");
        final Image cywil;

        cywil = new Image(new FileInputStream(overlay));

        File overlay2 = new File("city.png");
        final Image miasto;

        miasto = new Image(new FileInputStream(overlay2));

        File overlay3 = new File("cross.png");
        final Image skrzyzowanie;

        skrzyzowanie = new Image(new FileInputStream(overlay3));

        File overlay6 = new File("koksu.png");
        final Image koksu = new Image(new FileInputStream(overlay6));

        File overlay9 = new File("najman.png");
        final Image najman = new Image(new FileInputStream(overlay9));

        root.getChildren().add(animation);
        root.getChildren().add(animation2);

        Scene scene = new Scene(root, getWidth(), getHeight());

        stage.setTitle("Old Gotham");
        stage.setScene(scene);
        stage.show();

        final Duration oneFrameAmt = Duration.millis(1000 / 60);
        final KeyFrame oneFrame = new KeyFrame(oneFrameAmt,
                new EventHandler() {
                    @Override
                    public void handle(Event event) {

                        context2.drawImage(image, 0, 0);
                        //context2.drawImage(but1, 1250, 100, 100, 100);
                        int offset = 700;
                        context2.setLineWidth(5.0);
                        context2.setStroke(DARKGOLDENROD);

                        for (Road road : World.roads) {
                            if (road.getOrientation().equals("horizontal")) {
                                context2.strokeLine(road.getX(), road.getY(), road.getX2(), road.getY2());

                            } else if (road.getOrientation().equals("vertical")) {
                                context2.strokeLine(road.getX(), road.getY(), road.getX2(), road.getY2());

                            }

                        }
                        for (City city : World.cities) {
                            context3.drawImage(miasto, city.getX() - offset / 2, city.getY() - offset / 2, offset, offset);
                        }
                        int crossroadOffsetX = 150;
                        int crossroadOffsetY = 100;
                        for (Crossroad crossroad : World.crossroads) {
                            context2.drawImage(skrzyzowanie, crossroad.getX() - crossroadOffsetX / 2, crossroad.getY() - crossroadOffsetY / 2 + 20, crossroadOffsetX, crossroadOffsetY);
                        }

                        setCivilOffsetX(70);
                        setCivilOffsetY(40);
                        for (Civilian civilian : World.civilians) {
                            context2.drawImage(cywil, civilian.getX() - getCivilOffsetX() / 2, civilian.getY() - getCivilOffsetY() / 2, getCivilOffsetX(), getCivilOffsetY());
                        }
                        setBossOffsetX(70);
                        setBossOffsetY(40);
                        for (Boss boss : World.bosses) {

                            context2.drawImage(najman, boss.getX() - getBossOffsetX() / 2, boss.getY() - getBossOffsetY() / 2, getBossOffsetX(), getBossOffsetY());

                        }

                        setHeroOffsetX(70);
                        setHeroOffsetY(40);
                        for (SuperHero hero : World.superheroes) {

                            context2.drawImage(koksu, hero.getX() - getHeroOffsetX() / 2, hero.getY() - getHeroOffsetY() / 2, getHeroOffsetX(), getHeroOffsetY());

                        }

                    }
                });
        final Timeline tl = new Timeline(oneFrame);
        tl.setCycleCount(Animation.INDEFINITE);
        tl.play();
    }

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

    /**
     * @return the width
     */
    public static int getWidth() {
        return width;
    }

    /**
     * @param width the width to set
     */
    public void setWidth(int width) {
        this.width = width;
    }

    /**
     * @return the height
     */
    public static int getHeight() {
        return height;
    }

    /**
     * @param height the height to set
     */
    public void setHeight(int height) {
        this.height = height;
    }

}

The Canvas instances you are adding to the root Pane after you add the button ( animation and animation2 ) have the size of the scene, and these are covering everything below them, including the button, so you can't click on the button.

As a first simple solution, you can make these canvases transparent:

animation.setMouseTransparent(true);
animation2.setMouseTransparent(true);

But you can benefit from using different layouts, so you can have the graphic area in one pane and the controls in other. For instance, you could use a BorderPane . Something like this:

BorderPane root = new BorderPane();
Pane paneCenter= new Pane();
Canvas background= new Canvas(1200,1000);
Canvas animation = new Canvas(1200,1000);
Canvas animation2 = new Canvas(1200,1000);
paneCenter.getChildren().addAll(background, animation, animation2);
root.setCenter(paneCenter);

VBox paneRight = new VBox();
paneRight.setPrefSize(200, 1000);
paneRight.setPadding(new Insets(20));
paneRight.setAlignment(Pos.TOP_CENTER);
Button b1 = new Button("Spawn Civilian"); 
paneRight.getChildren().add(b1);
root.setRight(paneRight);

Scene scene = new Scene(root, 1400, 1000);    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM