-1

我有一个简单的 Java Swing应用程序,它显示了一个登录表单(一个 JFrame),它在一个带有背景图像的 JPanel 内部。

问题是,如果我使用图像的绝对路径放置图像的位置,我没有问题,但如果我尝试使用相对路径,则会出错,因为似乎找不到.png背景图像。

这是我的代码:

package com.test.login;

import javax.swing.JButton;

import java.awt.Container;
import java.awt.Dimension;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu.Separator;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

import net.miginfocom.swt.MigLayout;

import org.jdesktop.application.SingleFrameApplication;

public class LoginFrame2 extends SingleFrameApplication {

    private static final int FIXED_WIDTH = 550;
    private static final Dimension INITAL_SIZE = new Dimension(FIXED_WIDTH, 230);

    public static void main(String[] args) {
        System.out.println("DENTRO: LoginFrame() ---> main()");
        launch(LoginFrame2.class, args);
    }

    @Override
    protected void startup() {
        // TODO Auto-generated method stub
        System.out.println("Inside startup()");


        JFrame mainFrame = this.getMainFrame();         // main JFrame that represents the Windows
        mainFrame.setTitle("XCloud Login");

        mainFrame.setPreferredSize(INITAL_SIZE);
        mainFrame.setResizable(false);

        Container mainContainer = mainFrame.getContentPane();       // main Container into the main JFrame


        // JPanel creation and settings of the MigLayout on it:
        // JPanel externalPanel = new JPanel();
        JPanelWithBackground externalPanel = null;

        try {
            externalPanel = new JPanelWithBackground("/resources/logo.png");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        externalPanel.setLayout(new net.miginfocom.swing.MigLayout("fill"));

        externalPanel.add(new JLabel("Username"), "w 50%, wrap");

        JTextField userNameTextField = new JTextField(20);

        externalPanel.add(userNameTextField, "w 90%, wrap");

        externalPanel.add(new JLabel("Password"), "w 50%, wrap");
        JTextField pswdTextField = new JTextField(20);
        externalPanel.add(pswdTextField, "w 90%, wrap");

        JButton loginButton = new JButton("Login");

        externalPanel.add(loginButton, "w 25%, wrap");

        mainContainer.add(externalPanel);
        //mainFrame.add(mainContainer);

        show(mainFrame);


    }

}

logo.png文件位于我项目内的资源文件夹中(与 src 文件夹位于同一级别)。

我尝试访问此资源的行是:

externalPanel = new JPanelWithBackground("/resources/logo.png");

错误是:

DENTRO: LoginFrame() ---> main()
Inside startup()
javax.imageio.IIOException: Can't read input file!
    at javax.imageio.ImageIO.read(ImageIO.java:1275)
    at com.test.login.JPanelWithBackground.<init>(JPanelWithBackground.java:19)
    at com.test.login.LoginFrame2.startup(LoginFrame2.java:52)
    at org.jdesktop.application.Application$1.run(Application.java:187)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:672)
    at java.awt.EventQueue.access$400(EventQueue.java:81)
    at java.awt.EventQueue$2.run(EventQueue.java:633)
    at java.awt.EventQueue$2.run(EventQueue.java:631)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:642)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
11-nov-2013 10.49.42 org.jdesktop.application.Application$1 run
GRAVE: Application class com.test.login.LoginFrame2 failed to launch
java.lang.NullPointerException
    at com.test.login.LoginFrame2.startup(LoginFrame2.java:58)
    at org.jdesktop.application.Application$1.run(Application.java:187)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:672)
    at java.awt.EventQueue.access$400(EventQueue.java:81)
    at java.awt.EventQueue$2.run(EventQueue.java:633)
    at java.awt.EventQueue$2.run(EventQueue.java:631)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:642)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.lang.Error: Application class com.test.login.LoginFrame2 failed to launch
    at org.jdesktop.application.Application$1.run(Application.java:192)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:672)
    at java.awt.EventQueue.access$400(EventQueue.java:81)
    at java.awt.EventQueue$2.run(EventQueue.java:633)
    at java.awt.EventQueue$2.run(EventQueue.java:631)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:642)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Caused by: java.lang.NullPointerException
    at com.test.login.LoginFrame2.startup(LoginFrame2.java:58)
    at org.jdesktop.application.Application$1.run(Application.java:187)
    ... 14 more

我该如何解决?

4

4 回答 4

1

尝试不使用正斜杠。从 NetBeans 和 Eclipse 运行对我来说效果很好

"resources/logo.png" 
于 2013-11-11T09:57:22.640 回答
0

您的资源文件夹的输出文件夹是什么?

我想它是构建应用程序的根目录('bin'-目录,后来是 JAR 的根目录),在这种情况下,资源路径将是:

"/logo.png"

通常(取决于 IDE)您可以拥有多个源和资源文件夹,并为每个文件夹定义输出文件夹,以及过滤器在构建时应复制哪些内容。最通用的例子:

  • 源文件夹: /src, 输出文件夹: /bin, 过滤器: all but .java(编译器将创建并复制类文件)
  • 资源文件夹/rsc,输出文件夹:/bin,过滤器:所有文件。
  • 组装:内容/bin被打包成一个 JAR

示例:资源/rsc/images/icons/foo.png将被复制到/bin/images/icons/foo.png,并且它在运行时的路径('bin'作为 root 给出,或者打包到 JAR 中时)将是/images/icons/foo.png,这就是您在运行时用来加载此资源的路径。

于 2013-11-11T10:04:36.333 回答
0

我认为下一个问题:您尝试像下一个方式获取图像new ImageIcon("/resources/logo.png")尝试使用下一个代码: getClass().getResource("/resources/logo.png")。我认为它对你有帮助。

编辑:File从它创建使用

    URL resource = getClass().getResource("/resources/logo.png");
    File f = new File(resource.getFile());

阅读有关图标的更多信息。

于 2013-11-11T10:07:50.963 回答
0

您的项目的根可能甚至在您的“src”目录之前。尝试将路径设置为

“/src/path/to/your/resources/logo.png”

或像这样相对导航

“../资源/logo.png”

另一种方法是将根目录设置为变量。这可能会派上用场以供以后使用

private final String _RESOURCE_DIR = "/src/path/to/resources/";
File png = new File(_RESOURCE_DIR + "logo.png");
于 2013-11-11T10:09:34.000 回答