SwingFXUtils.toFXImage не работает в банке - PullRequest
0 голосов
/ 06 мая 2020

У меня есть JavaFX Canvas для рисования GameUnit с использованием метода drawUnit () . Когда я запускаю приложение из IntelliJ с помощью Maven, ошибок не возникает. Но когда я компилирую Jar и запускаю его, метод SwingFXUtils.toFXImage () нарушает работу моего приложения. Я на 100% уверен, что проблема именно в этом методе, потому что проверял. Метод SpriteAnimation.nextSprite () возвращает BufferedImage .

Это основной класс:

public class Game extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        stage.setTitle("The Game");
        stage.setFullScreenExitKeyCombination(new KeyCharacterCombination(""));
        stage.setFullScreenExitHint("");
        stage.setFullScreen(true);

        Group root = new Group();
        Scene scene = new Scene(root);

        GameCanvas canvas = new GameCanvas();
        canvas.widthProperty().bind(scene.widthProperty());
        canvas.heightProperty().bind(scene.heightProperty());

        root.getChildren().add(canvas);

        new AnimationTimer() {
            @Override
            public void handle(long now) {
                canvas.clear();
                canvas.drawUnits();
            }
        }.start();

        stage.setScene(scene);

        stage.show();
    }
}

Это класс GameCanvas:

public class GameCanvas extends Canvas {
    public void drawUnits(){
        GameData.getAllUnits().forEach(this::drawUnit);
    }

    public void drawUnit(GameUnit unit){
        GraphicsContext context = getGraphicsContext2D();
        SpriteAnimation animation = unit.getAnimation();
        context.drawImage(
                SwingFXUtils.toFXImage(animation.nextSprite(), null),
                unit.getPosition().getX(), unit.getPosition().getY(),
                unit.getWidth(), unit.getHeight()
        );
    }

    public void clear() {
        GraphicsContext context = getGraphicsContext2D();
        context.clearRect(0, 0, getWidth(), getHeight());
    }
}

Это класс SpriteAnimation:

public class SpriteAnimation {
    private BufferedImage[] sprites;
    private int counter;
    private int speed;
    private int delay;

    public SpriteAnimation(BufferedImage[] sprites, int speed) {
        this.sprites = sprites;
        this.speed = speed;
        counter = 0;
        delay = 0;
    }

    public BufferedImage nextSprite() {
        if (delay == speed - 1) {
            delay = 0;
            counter++;
        }
        else {
            delay++;
        }
        return sprites[counter % sprites.length];
    }
}

Это класс ImageLoader:

public class ImageLoader implements Loader<BufferedImage> {
    private static final Logger LOGGER = Logger.getLogger(ImageLoader.class.getName());

    @Override
    public BufferedImage upload(String pathToResource) {
        try (InputStream inputStream = ImageLoader.class.getClassLoader().getResourceAsStream(pathToResource))
        {
            if (inputStream != null) {
                return ImageIO.read(inputStream);
            }
        } catch (IOException e) {
            LOGGER.log(Level.INFO, "Can not upload image!");
        }
        return null;
    }
}

Это пример использования класса ImageLoader:

private static final ImageLoader LOADER = new ImageLoader();


BufferedImage[] unitsImage = {
                LOADER.upload("image/character/TileA1.png"),
                LOADER.upload("image/character/TileA2.png")
        };

Это pom-файл:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.some.game</groupId>
    <artifactId>The_Game</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.some.game</groupId>
            <artifactId>GameData</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.some.game</groupId>
            <artifactId>ResourceLoaders</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>org.some.game.Game</mainClass>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>org.some.game.GameLauncher</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Вот как это должно работать: введите описание изображения здесь

Вот как это работает: введите описание изображения здесь

Это результат выполнения jar-файла из командной строки:

enter image description here

В этом примере файл jar работает и может быть запущен щелчком мыши

Воспроизведенная проблема в новом проекте: POM-файл:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-graphics</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>FXApp</mainClass>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>FXAppLauncher</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Основной класс - FXApp:

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.awt.image.BufferedImage;

public class FXApp extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("Test");
        Group root = new Group();
        Scene scene = new Scene(root);

        BufferedImage image = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
        SwingFXUtils.toFXImage(image, null);

        stage.setScene(scene);
        stage.show();
    }
}

Класс -launcher FXAppLauncher:

public class FXAppLauncher {
    public static void main(String[] args) {
        FXApp.main(args);
    }
}

Структура проекта: введите описание изображения здесь

1 Ответ

1 голос
/ 06 мая 2020

Посмотрев на ваш файл pom, вам нужно добавить:

    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-swing</artifactId>
        <version>11</version>
    </dependency>

Он должен включать модуль Swing.

Вот небольшой класс для тестирования, если я не включу javafx.swing модуль, то он показывает мне сообщение об ошибке.

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Color;
import javafx.scene.text.Text;


public class BuffToFx extends Application{


@Override
    public void start(Stage primaryStage) throws Exception{
        FlowPane root = new FlowPane(5, 5);

        primaryStage.setTitle("BufferImage to Fx");

        BufferedImage img = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
        Graphics g = img.getGraphics();
        g.setColor(Color.RED);
        g.drawOval(256, 256, 128, 128);

        try{
            ImageView view = new ImageView( javafx.embed.swing.SwingFXUtils.toFXImage(img, null) );
            root.getChildren().add(view);
        } catch(Error e){
            Text error = new Text(e.toString());
            root.getChildren().add(error);
        }
        Scene scene = new Scene(root, 790, 675);
        primaryStage.setScene(scene);

        primaryStage.show();
    }

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