从Eclipse调试SplashScreen而不生成Jar

时间:2011-08-02 01:10:49

标签: java eclipse debugging swing splash-screen

我在网上搜索但找不到这个问题的答案:

我需要根据您正在访问的模块调试更改SplashScreen的应用程序的功能。

我知道代码:

SplashScreen splash = SplashScreen.getSplashScreen();

当您通过时,可用于获取实例:

  • 从命令行启动:java -splash:path / image.gif ClassFile
  • 在清单中启动图片:splashscreen-image:img / SplashNomina.gif

当我尝试通过从Eclipse中的VM args传递-splash值来运行应用程序时,它仍无效。

实际上,SplashScreen.getSplashScreen()始终为NULL。 我一直试图通过而没有成功:

  • -splash:Image.gif的
  • -Dsplash = Image.gif的

现在我看到这个Splash api有很多限制,因为总是需要传递一个参数。我认为能够在运行时传递参数会更加灵活:(

任何帮助都会非常感激!

3 个答案:

答案 0 :(得分:12)

好的,这也咬了我。

我建了一个可运行的jar 使用清单条目

SplashScreen-Image: MyGraphic.jpg

它按预期工作。

从Eclipse中,将VM arg指定为

-splash:MyGraphic.jpg

没有这样的运气

SplashScreen.getSplashScreen()返回null。

原因是JDK中的SplashScreen.getSplashScreen()实现了大脑死亡(至少1.6)。我认为。如果不了解本机代码正在做什么,这很难说。但是,这是java.awt.SplashScreen中的这个方法。我不确定它是否被调用但是研究它确实为我提供了在Eclipse中使用它所需的基本线索:

public synchronized URL getImageURL() throws IllegalStateException {
    checkVisible();
    if (imageURL == null) {
        try {
            String fileName = _getImageFileName(splashPtr);
            String jarName = _getImageJarName(splashPtr);
            if (fileName != null) {
                if (jarName != null) {
                    imageURL = new URL("jar:"+(new File(jarName).toURL().toString())+"!/"+fileName);
                } else {
                    imageURL = new File(fileName).toURL();
                }
            }
        }
        catch(java.net.MalformedURLException e) {
            // we'll just return null in this case
        }
    }
    return imageURL;
}

请注意,对于文件(即命令行而不是jar启动),它不会使用getResource()来获取URL,而是打开相对于CWD的文件。由于Eclipse运行配置默认从项目的根目录运行,因此答案是将路径指定为相对路径,而不是期望进行类路径查找。

因此,由于我使用maven构建,我的图像位于src / main / resources / MyGraphic.jpg。将其指定为命令行参数:即

-splash:src/main/resources/MyGraphic.jpg 

允许它在Eclipse中工作(或者,我猜,任何命令行)

我不确定为什么会这样,因为getImageURL方法没有被getSplashScreen()调用,但是它可以工作。

对我而言,这对Sun / Oracle来说是一种脑死亡。他们可以轻松地完成类路径查找 imageURL = getResource(filename)但他们没有。

简短的回答是,Splash Screen命令行语法是指相对于当前工作目录的文件名,而不是相对于类路径的文件名。

答案 1 :(得分:4)

我回答了3年后,但我遇到了同样的问题,我试图解决。 我找到了解决方案,我认为这对每个人都有用。

您必须创建启动配置,在 VM参数中指定参数 -splash:image.gif 。此参数引用项目的根目录(不是/ bin或/ src)。因此,您必须将图像放在与/ bin和/ src相同的级别(或者您可以在-splash选项中指定不同的路径)。

当您从'export'导出可运行的JAR,指定之前创建的启动配置时,它表示'不能包含VM参数,您必须从命令行指定'(并且它不包括您的image.gif在根)。 因此,如果您想要一个带有启动图像的可运行jar,您可以参考stackoverflow上的另一个主题,我不再找到它了。有人回答说最好的解决方案是FatJar。您可以按以下步骤操作:导出>其他>胖罐出口商。勾选'选择清单文件',指定包含'SplashScreen-Image:splash.gif'的MANIFEST.MF(如果你不知道如何创建,取消选中此复选框,创建一个默认的jar,修改创建的jar和包括它)。在导出的下一页中,确保使用“add dir”按钮将您的图像包含在jar中(它包含指定给项目根目录的目录的内容,因此请注意清单中的目录)。 它对我有用。

因此,如果您想使用eclipse运行,请将启动图像添加到根目录,并在VM参数中指定-splash:image.gif。如果你想导出一个JAR,FatJar插件就像我指定的那样为我工作。

我希望它有所帮助:)

(对不起我的英文,我不是英文:P)

答案 2 :(得分:3)

好吧,伙计们,我决定采用自己独立的方式,因为Splash课程太单一了,所以我在这里上课:

import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;


public class SplashWindow extends JFrame {

  private static final long serialVersionUID = 9090438525613758648L;

  private static SplashWindow instance;

  private boolean paintCalled = false;

  private Image image;

  private SplashWindow(Image image) {
    super();
    this.image = image;
    JLabel label = new JLabel();
    label.setIcon(new ImageIcon(image));
    this.add(label);    
    this.setUndecorated(true);
    this.setAlwaysOnTop(true);
    this.pack();
    this.setLocationRelativeTo(null);

  }

  public static void splash(URL imageURL) {
    if (imageURL != null) {
      splash(Toolkit.getDefaultToolkit().createImage(imageURL));
    }
  }

  public static void splash(Image image) {
    if (instance == null && image != null) {
      instance = new SplashWindow(image);
      instance.setVisible(true);

      if (!EventQueue.isDispatchThread() && Runtime.getRuntime().availableProcessors() == 1) {

        synchronized (instance) {
          while (!instance.paintCalled) {
            try {
              instance.wait();
            } catch (InterruptedException e) {
            }
          }
        }
      }
    }
  }

  @Override
  public void update(Graphics g) {
    paint(g);
  }

  @Override
  public void paint(Graphics g) {
    g.drawImage(image, 0, 0, this);
    if (!paintCalled) {
      paintCalled = true;
      synchronized (this) {
        notifyAll();
      }
    }
  }

  public static void disposeSplash() {
    instance.setVisible(false);
    instance.dispose();
  }
}

希望它可以帮到某人;)