JAR-файлы не работают правильно и ресурсы не загружаются - PullRequest
0 голосов
/ 25 июня 2018

У меня серьезные проблемы с неправильной работой файлов Jar. Мой проект прекрасно работает в Eclipse, но при экспорте он просто не работает вообще. У меня возникла проблема, подобная этой: Запускаемые JAR-файлы отсутствуют Изображения / Файлы (Ресурсы) и почти точная проблема с этим Запускаемый экспортированный JAR-файл не работает так, как это должно быть в случае выхода из Eclipse

Я использовал некоторые из методов, но ни один из них не сработал, единственный, который сделал, - это сказал мне запустить файл jar в командной строке, чтобы проверить, есть ли ошибки. И я думаю, что мог бы сузить его до папки с ресурсами. Оно не в самой банке, а в содержимом. Есть ли способ это исправить? Потому что это может быть проблемой. Другое дело, что эта программа представляет собой игру, и, как я разработал карты, они должны загружаться из "res / maps / map.txt". По какой-то причине, не объясненной мне при изучении, как это сделать, «res /» должен быть перед картами, но когда я загружаю текстуры, это другая история, так что, возможно, мой источник знаний не такой умный. Для справки вот код для загрузки карт и изображений.

Изображения (Работает нормально в соответствии с Cmd Prompt):

package com.mthomps.engine.gfx;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageLoader {

public static BufferedImage loadImg(String path){

    try {
        return ImageIO.read(ImageLoader.class.getResource(path));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.exit(1);
    }
    return null;
}

}

Utils (читает текстовый файл для карты):

package com.mthomps.engine.utils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Utils {

public static String loadFileAsString(String path){
    StringBuilder builder = new StringBuilder();

    try{
        BufferedReader br = new BufferedReader(new FileReader(path));
        String line;
        while((line = br.readLine()) != null)
            builder.append(line + "\n");
        br.close();
    }catch(IOException e){
        e.printStackTrace();
    }

    return builder.toString();

}

public static int parseInt(String number){
    try{
        return Integer.parseInt(number);
    }catch(NumberFormatException e){
        e.printStackTrace();
        return 0;
    }
}

}

Карта:

package com.mthomps.engine.main.map;

import java.awt.Graphics;

import com.mthomps.game.tiles.Tile;
import com.mthomps.engine.main.Handler;
import com.mthomps.enigne.utils.Utils;

public class Map {

private Handler handler;
private int width, height;
private int spawnX, spawnY;
private int[][] tiles;

public Map(Handler handler, String path){
    this.handler = handler;
    loadMap(path);
}

public void tick(){

}

public void render(Graphics g){
    int xStart = (int) Math.max(0, handler.getGameCamera().getxOffset() / Tile.TILEWIDTH);
    int xEnd = (int) Math.min(width, (handler.getGameCamera().getxOffset() + handler.getWidth()) / Tile.TILEWIDTH + 1);
    int yStart = (int) Math.max(0, handler.getGameCamera().getyOffset() / Tile.TILEHEIGHT);
    int yEnd = (int) Math.min(height, (handler.getGameCamera().getyOffset() + handler.getHeight()) / Tile.TILEHEIGHT + 1);

    for(int y = yStart; y < yEnd; y++){
        for(int x = xStart; x < xEnd; x++){
            getTile(x, y).render(g, (int) (x * Tile.TILEWIDTH - handler.getGameCamera().getxOffset()), (int) (y * Tile.TILEHEIGHT - handler.getGameCamera().getyOffset()));
        }
    }
}

public Tile getTile(int x, int y){
    if(x < 0 || y < 0 || x >= width || y >= height)
        return Tile.devWhite;

    Tile t = Tile.tiles[tiles[x][y]];
    if(t == null)
        return Tile.devWhite;
    return t;
}

private void loadMap(String path){
    String file = Utils.loadFileAsString(path);
    String[] tokens = file.split("\\s+");
    width = Utils.parseInt(tokens[0]);
    height = Utils.parseInt(tokens[1]);
    spawnX = Utils.parseInt(tokens[2]);
    spawnY = Utils.parseInt(tokens[3]);

    tiles = new int[width][height];
    for(int y = 0; y < height; y++){
        for(int x = 0; x < width; x++){
            tiles[x][y] = Utils.parseInt(tokens[(x + y * width) + 4]);
        }
    }
}

}

GameState (куда загружается карта. Требуется «res /» по какой-то странной причине):

package com.mthomps.game.states;

import java.awt.Color;
import java.awt.Graphics;

import com.mthomps.game.entity.mob.Player;
import com.mthomps.engine.main.Handler;
import com.mthomps.engine.main.map.Map;



public class GameState extends State{

private Player player;
private Map maze;

public GameState(Handler handler){
    super(handler);
    player = new Player(handler, 256, 256);
    maze = new Map(handler, "res/maps/maze/maze.txt");
    handler.setMap(maze);

}

@Override
public void tick() {
    maze.tick();
    player.tick();

}

@Override
public void render(Graphics g) {
    maze.render(g);
    player.render(g);

}

    }

Как я уже сказал, этот код есть только для справки, я чувствую, что мне нужна папка "res" в моем банке, а не только ее содержимое. Если есть какой-либо способ, которым я мог сделать это, или любые ошибки в коде, пожалуйста, сообщите мне. Командная строка не сказала, что что-то не так с моим классом ImageLoader, но, возможно, есть деталь, которую я пропустил. При запуске программы ничего не отображается, только окно.

Ответы [ 3 ]

0 голосов
/ 25 июня 2018
BufferedReader br = new BufferedReader(new FileReader(path));

Встроенный ресурс недоступен как File!

Получите URL через getResource(..) и используйте его вместо этого.

EG

URL url = getClass().getResource("/path/to/resource.res");
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
0 голосов
/ 25 июня 2018

При экспорте файла Jar Runnable в Eclipse все данные из папки bin/ будут скопированы в архив Jar.Поэтому ваша цель состоит в том, чтобы ваш компилированный исходный код и ваши ресурсы находились в папке bin/ после компиляции.

Во время компиляции Eclipse сначала компилирует все классы из ваших исходных папок и копирует их в bin/папка.Затем Eclipse просто копирует все файлы, не относящиеся к классу, из ваших исходных папок в папку bin/.

Если вы хотите, чтобы все ваши ресурсы находились в папке res/ внутри папки bin/, вам необходимоВаша папка res/ находится внутри исходной папки .Вы можете иметь его в src/ или создать новую исходную папку, например resources/, которая содержит вашу папку res/.

Чтобы получить доступ к вашим ресурсам во время выполнения, я предлагаю вам использовать Class::getResource(String name), как вы уже делаете для загрузки изображений.Вы можете добавить эту строку перед инициализацией BufferedReader в Utils::loadFileAsString(String path):

path = Utils.class.getResource(path).getFile();

Это должно обновить относительный путь, который вы получаете в качестве параметра, до правильного абсолютного пути. Очень важно, чтобы path начинался с /! Например, /res/maps/map.txt действует, а res/... - нет.Только с / в качестве первого символа getResource не ищет путь относительно пакета текущего класса, но относительно «корневого» пакета.( Документы )

Если у вас есть еще вопросы (или они все еще не работают), не стесняйтесь спрашивать!

0 голосов
/ 25 июня 2018

Вы должны предоставить свои ресурсы карты, где ваш файл JAR может получить к ним доступ. Самый простой способ сделать это - включить их в файл JAR при его сборке в Eclipse. Структура каталогов внутри JAR может быть любой, какой вы пожелаете. Не существует правила, которое говорит, что «res /» должно быть перед «map /». Вы определяете структуру каталогов, потому что ваш код - это то, к чему вы обращаетесь.

Первый связанный с вами вопрос предлагает использовать Class.getResource("/images/yourImageName.extension");. Как видно из документации, это возвращает объект URI. В вашем случае вам, вероятно, понадобится тесно связанный Class.getResourceAsStream("/images/yourImageName.extension");, который возвращает InputStream, который вы затем можете передать BufferedReader, и остальная часть вашей логики для чтения файла может быть такой же.

...