Отладка SplashScreen из Eclipse без создания Jar - PullRequest
6 голосов
/ 02 августа 2011

У меня есть поиск по всей сети, но я не смог найти ответ на этот вопрос:

Мне нужно отладить работу приложения, которое изменяет SplashScreen в зависимости от модуля, к которому вы обращаетесь.

Я знаю, что код:

SplashScreen splash = SplashScreen.getSplashScreen();

Может использоваться для получения экземпляра, когда вы передаете:

  • Всплеск из командной строки: java -splash: path / image.gif ClassFile
  • Заставить изображение в манифесте: splashscreen-image: img / SplashNomina.gif

Тем не менее, когда я пытался запустить приложение, передав значение -splash из аргументов VM в Eclipse, оно не работало.

Возможно ли это, поскольку SplashScreen.getSplashScreen () всегда имеет значение NULL. Я пытался пройти без успеха:

  • -splash: image.gif
  • -Dsplash = image.gif

Прямо сейчас я вижу много ограничений в этом Splash API, так как всегда требуется, чтобы был передан параметр. Я думаю, что было бы гораздо более гибким, чтобы иметь возможность просто передать параметр во время выполнения: (

Любая помощь действительно будет оценена!

Ответы [ 3 ]

12 голосов
/ 11 ноября 2011

ОК, меня это тоже укусило.

Я построил работающую банку с декларацией

SplashScreen-Image: MyGraphic.jpg

и работает как положено.

Из Eclipse, указав аргумент виртуальной машины как

-splash:MyGraphic.jpg

нет такой удачи

SplashScreen.getSplashScreen () возвращает ноль.

Причиной этого является мертвая реализация SplashScreen.getSplashScreen () в JDK (как минимум 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 (), но он РАБОТАЕТ.

Для меня это своего рода умопомрачительное со стороны Солнца / Оракула. Они могли бы легко сделать поиск classpath с чем-то вроде imageURL = getResource (имя файла), но они этого не сделали.

Краткий ответ: синтаксис командной строки Splash Screen относится к имени файла относительно текущей рабочей директории, а не относительно пути к классам.

4 голосов
/ 05 апреля 2014

Я отвечаю 3 года спустя, но у меня была та же проблема, и я пытался решить. Я нашел решение и думаю, что оно будет полезным для всех.

Необходимо создать конфигурацию запуска, указав в VM аргументы параметр -splash: image.gif . Этот параметр относится к корневому каталогу проекта (не / bin или / src). Поэтому вы должны поместить свой образ на тот же уровень, что и / bin и / src (или вы можете указать другой путь в опции -splash).

Когда вы экспортируете исполняемый JAR-файл из «export», указав конфигурацию запуска, которую вы создали ранее, он говорит: «не может включать аргументы VM, вы должны указать из командной строки» (и он не включает ваш image.gif в корне). Так что, если вы хотите иметь исполняемый jar с вашим изображением-заставкой, вы можете обратиться к другой теме по stackoverflow, которую я больше не нахожу. Кто-то ответил, что лучшим решением является FatJar. Вы можете действовать следующим образом: экспорт> другой> экспортер жировых банок. Отметьте галочкой «выбрать файл манифеста», указав файл MANIFEST.MF, содержащий «SplashScreen-Image: splash.gif» (если вы не знаете, как его создать, снимите этот флажок, создайте банку со стандартным, измените созданный и включи это). На следующей странице экспорта обязательно добавьте свои изображения в банку с помощью кнопки «Добавить каталог» (она включает в себя содержимое каталога, указанного в корневом каталоге проекта, поэтому обратите внимание на каталог в манифесте). ). У меня это сработало.

Поэтому, если вы хотите запустить с eclipse, добавьте изображение-заставку в корневой каталог и укажите -splash: image.gif в аргументах виртуальной машины. Если вы хотите экспортировать JAR, плагин FatJar работал для меня, как я указал.

Надеюсь, это поможет:)

(простите за мой английский, я не англичанин: P)

3 голосов
/ 05 августа 2011

Ну, ребята, я решил, что вы идете своим независимым путем, потому что класс 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();
  }
}

Надеюсь, это кому-нибудь поможет;)

...