2011-08-02 7 views
5

Tengo buscar en toda la web, pero no pudo encontrar respuesta a esta pregunta:depuración SplashScreen de Eclipse sin generar el tarro

necesito para depurar el funcionamiento de una aplicación que cambia el SplashScreen basado en el módulo que está accediendo

sí sé que el código:

SplashScreen splash = SplashScreen.getSplashScreen(); 

Se puede utilizar para obtener la instancia cuando se pasa bien:

  • Splash desde la línea de comandos: java -splash: ruta/imagen.gif archivo de clase
  • imagen
  • Splash en el manifiesto: splashscreen imagen: img/SplashNomina.gif

Aún cuando intenté ejecutar la aplicación pasando el valor -splash desde VM args en Eclipse no funcionó.

¿Es realmente posible como SplashScreen.getSplashScreen() siempre es NULL. he estado tratando de pase sin éxito:

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

En este momento veo un montón de limitaciones en este api Splash, ya que siempre se requiere que se pase un parámetro. Creo que sería mucho más flexible para poder simplemente pasar el parámetro en tiempo de ejecución :(

Cualquier ayuda woult muy apreciada!

+0

Ha intentado _VM Arguments_ en su _Run Configuration_? – trashgod

+0

Sí, he intentado pasar los argumentos desde allí. Parece que el problema radica en que el argumento -splash: image depende de un archivo ubicado dentro del mismo directorio y estoy tratando de incluir la imagen dentro del archivo Jar. – will824

+0

Lo siento, lo leí mal. También puede probar esta [utilidad] (http://sites.google.com/site/drjohnbmatthews/manifesto) para verificar el atributo 'SplashScreen-Image' _in situ_. – trashgod

Respuesta

11

bien, esto me ha mordido también.

me construyeron un frasco ejecutable con entrada de manifiesto

SplashScreen-Image: MyGraphic.jpg 

y funciona como se supone que debe.

De Eclipse, especificando el VM arg como

-splash:MyGraphic.jpg 

no tan suerte

SplashScreen.getSplashScreen() devuelve un valor nulo.

La razón de esto es la implementación de muerte cerebral de SplashScreen.getSplashScreen() en el JDK (al menos 1.6). Creo. Es algo difícil de decir sin entrar en lo que está haciendo el código nativo. Pero, aquí está este método de java.awt.SplashScreen.No estoy seguro de si se llama, pero su estudio no me proporcione la clave esencial que necesitaba para conseguir este trabajo en 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; 
} 

Tenga en cuenta que en el caso de un archivo (es decir, la línea de comandos en lugar de jarra lanzamiento) no está haciendo un getResource() para obtener el URL pero abriendo un archivo relativo al CWD. Dado que Eclipse ejecuta las configuraciones predeterminadas para ejecutarse desde la raíz del proyecto, la respuesta es especificar la ruta como una ruta relativa y no esperar una búsqueda de ruta de clase.

Por lo tanto, desde que estoy construyendo con maven, mi imagen se encuentra en src/main/resources/MyGraphic.jpg. La especificación de esta como el parámetro de línea de comandos: es decir

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

le permite trabajar en Eclipse (o, supongo, cualquier línea de comandos)

No estoy seguro de por qué esto es, ya que el método es getImageURL NO llamado por getSplashScreen() pero SI FUNCIONA.

Para mí esto es una especie de muerte cerebral por parte de Sun/Oracle. Podrían haber hecho fácilmente una búsqueda de classpath con algo como imageURL = getResource (filename) pero no lo hicieron.

La respuesta corta es que la sintaxis de la línea de comando de la pantalla de bienvenida hace referencia a un nombre de archivo relativo al directorio de trabajo actual, no relativo a la ruta de clase.

+0

Gran análisis sobre esto. Gracias por su esfuerzo para explicar este asunto, aún estaría a oscuras sin su respuesta. :) – will824

3

Bueno chicos, yo decidí ir a mi manera independiente, porque la clase es Splash demasiado monolítica, asi que aquí pongo mi clase:

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(); 
    } 
} 

espero que ayude a alguien;)

3

Estoy respondiendo 3 años después pero tuve el mismo problema y traté de resolverlo. Encontré la solución, y creo que sería útil para todos.

usted tiene que crear una configuración de ejecución, especificando en los argumentos de VM la -splash parámetro : imagen.gif. Este parámetro hace referencia al directorio raíz del proyecto (no/bin o/src). Por lo tanto, debe colocar su imagen en el mismo nivel que/bin y/src (o puede especificar una ruta diferente en la opción -splash).

Cuando exporta el JAR ejecutable de 'export' especificando la configuración de inicio que creó anteriormente, dice 'no puede incluir argumentos de VM, debe especificar desde la línea de comandos' (y no incluye su imagen. gif en la raíz). Así que si quiere tener un jar ejecutable con su imagen splash, puede referirse a otro tema en stackoverflow que ya no encuentro. Alguien respondió que la mejor solución es FatJar. Puede proceder de la siguiente manera: export> other> exportador de tarros gordos. Marque 'seleccionar archivo de manifiesto', especificando un MANIFEST.MF que contenga 'SplashScreen-Image: splash.gif' (si no sabe cómo crear, desmarque esta casilla de verificación, cree un jar con el predeterminado, modifique el creado y incluirlo). En la página siguiente de la exportación, asegúrese de incluir sus imágenes en el contenedor con el botón 'agregar directorio' (incluye el contenido del directorio especificado en el directorio raíz del proyecto, así que preste atención con el directorio en el manifiesto) Me funcionó.

Por lo tanto, si desea ejecutar con eclipse, agregue la imagen de bienvenida al directorio raíz y especifique -splash: image.gif en los argumentos de VM. Si desea exportar un JAR, el complemento FatJar funcionó para mí tal como lo especifiqué.

espero que ayude :)

(lo siento por mi Inglés, no soy Inglés: P)

+1

Muchas gracias por responder, no importa si esta fue una pregunta de hace 3 años, ya que algunas personas podrían estar teniendo este problema justo ahora y ¡tu contribución es muy valiosa! :) – will824

Cuestiones relacionadas