![](/img/trans.png)
[英]Loading resources like images while running project distributed as JAR archive
[英]Jar files not running correctly and resources not loading
我的Jar文件无法正常运行时遇到了一些严重的麻烦。 我的项目在Eclipse中工作正常,但是在导出时根本无法工作。 我有一个与此类似的问题:可运行的JAR缺少图像/文件(资源),并且几乎完全是此Runnable导出的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;
}
}
实用程序(读取地图的txt文件):
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);
}
}
就像我说的那样,该代码仅供参考,我觉得我需要jar中的“ res”文件夹,而不仅仅是它的内容。 如果有任何方法可以执行此操作,或者代码中有任何错误,请告诉我。 命令提示符没有说ImageLoader类有什么问题,但是也许我错过了一个细节。 当我运行程序时,没有任何显示,只有窗口。
您需要提供地图资源,以便您的JAR文件可以访问它们。 最简单的方法是在Eclipse中构建文件时将它们包括在JAR文件中。 JAR内部的目录结构可以是您想要的任何内容。 没有规则说“ res /”必须在“ map /”之前。 您定义目录结构是因为您的代码可以访问它。
您链接的第一个问题建议使用Class.getResource("/images/yourImageName.extension");
。 从文档中可以看到,这将返回URI
对象。 就您而言,您可能需要密切相关的Class.getResourceAsStream("/images/yourImageName.extension");
它返回一个InputStream
,您可以将其传递给BufferedReader
,然后其余逻辑读取文件可以是相同的。
BufferedReader br = new BufferedReader(new FileReader(path));
嵌入式资源不能作为File
访问!
通过getResource(..)
获取URL
并使用它。
URL url = getClass().getResource("/path/to/resource.res");
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
Eclipse中的Runnable Jar File Export将把bin/
文件夹中的所有内容复制到jar归档文件中。 因此,您的目标是在编译后将已编译的源代码和资源保存在bin/
文件夹中。
在编译过程中,Eclipse首先编译源文件夹中的所有类,然后将它们复制到bin/
文件夹中。 然后,Eclipse只是将所有非类文件从您的源文件夹复制到bin/
文件夹中。
如果要将所有资源都放在bin/
文件夹中的res/
bin/
文件夹中,则必须将res/
文件夹放在source文件夹中 。 您可以将其放在src/
也可以创建一个新的源文件夹,例如resources/
,其中包含您的res/
文件夹。
要在运行时访问资源,建议您像使用图像加载一样使用Class::getResource(String name)
。 您可以在Utils::loadFileAsString(String path)
中的BufferedReader
初始化之前添加此行:
path = Utils.class.getResource(path).getFile();
这会将您作为参数获取的相对路径更新为正确的绝对路径。 path
以/
开头很重要。 例如, res/...
/res/maps/map.txt
res/...
/res/maps/map.txt
有效,而res/...
无效。 仅使用/
作为第一个字符, getResource
不会查找相对于当前类的程序包的路径,而是相对于“根”程序包的路径。 ( 文档 )
如果您还有其他问题(或者仍然无法解决),请随时提出!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.