У меня есть 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-файла из командной строки:
В этом примере файл 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);
}
}
Структура проекта: введите описание изображения здесь