2009-02-03 16 views
11

Estoy creando una aplicación Java que procesará algo y luego necesita mostrar un mensaje para dar su opinión.¿La forma más rápida de crear un diálogo de mensaje de Java (swing/awt/other)?

Sin embargo, parece ser increíblemente lento, tardando más de dos segundos en regresar.

Me desnudé la fuente hasta el culpable aparente, y aquí es el código utilizado:

package SwingPlay; 

import javax.swing.JFrame; 

public class Dialog 
{ 

    public static void main(String[] args) 
    { 
     JFrame frame = new JFrame("DialogDemo"); 
    } 

} 

estoy ejecutando esto desde la línea de comandos:

java -classpath . SwingPlay.Dialog 

como se puede ver - No hago nada más que crear un JFrame, ni siquiera mostrarlo.

En caso de que sea relevante, aquí está mi java -version de salida:

java version "1.6.0_11" 
Java(TM) SE Runtime Environment (build 1.6.0_11-b03) 
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing) 

Y esto es (actualmente) que se ejecuta en contra Win XP SP2.


Entonces, primera pregunta: ¿Por qué es tan lento?

Lo que es más importante, solo quiero que se muestre un mensaje simple (GUI, no cmdline) sin demora. ¿Alguien puede proporcionar algún código para hacer esto?


Actualización:

Un poco de historia podría ser útil:
Estoy creando una aplicación que tendrá muchas 'cabezas' (es decir, diferentes interfaces de usuario todos con las mismas clases básicas que se pueden hacer las partes complejas).
Actualmente tengo una cabeza de línea de comando pura que funciona bien, responde de inmediato.
También tendré una aplicación estándar con un punto regular & haga clic en GUI, y no preveo problemas con este bit.
En lo que estoy trabajando actualmente es un híbrido de estos dos: se lanzará desde un cuadro Ejecutar (o un iniciador similar), posiblemente con argumentos, y solo necesita responder, efectivamente, con un mensaje de estado, que puede descartarse con presionar una tecla.

Este último es el lugar donde se enfoca la pregunta.

Aunque no me opongo a usar mi versión de línea de comandos existente con scripts de shell (¡aunque no pensé que fuera necesario!), Las respuestas existentes parecen sugerir que las cosas no se ejecutan tan rápido para mí como lo son para otros, un ejemplo toma 1460ms para mí, frente a 70ms, una diferencia significativa.

Respuesta

0

Lo que probablemente está buscando es el new SplashScreen functionality in Java 6. En lugar de tener que esperar a que se cargue la JVM (siempre hay un costo para cargar cualquier máquina virtual), esto cargará una pantalla de antemano.

+0

No estoy buscando mostrar una imagen estática, sino una parte dinámica de texto. Para decirlo de otra manera, quiero redireccionar stdout a un cuadro de mensaje GUI. Si realmente uso System.out.println vuelve lo suficientemente rápido, pero obviamente no en el formato correcto. –

2

También sería mucho más rápido crear un AWT Window (o tal vez un Frame) en lugar de un JFrame porque este último tiene que extraer un montón de archivos de clase adicionales.

+0

Si bien java.awt.Frame es más rápido, aún demorará más de un segundo. :( –

+0

Sí, lamentablemente no es realmente rápido. Si tiene todo en un solo programa, cree el marco antes de realizar la acción real y luego simplemente muéstrelo cuando haya terminado. No será más rápido en general, pero ciertamente se verá de esa manera. – Bombe

+0

La acción real ocurre en un abrir y cerrar, así que desafortunadamente ni siquiera ganaré esa ilusión ... –

1

Ah, y si realmente no necesita mostrar el cuadro de diálogo de Java, puede buscar usando KDialog (o su homólogo de GNOME) o algo similar.

+0

El núcleo de la aplicación necesita ser Java, pero si usar incluso una interfaz básica es demasiado lenta, entonces puede hacer con el uso de scripts de shell para mostrar la respuesta del programa. –

+0

Sí, la primera instanciación de algo relacionado con GUI en Java siempre será lento (er), no hay manera de evitar eso, a menos de volverse nativo (ya sea a través de JNI o ​​con Runtime.exec()). – Bombe

4

Yo usaría un JOptionPane para mostrar el mensaje. Aquí hay un ejemplo simple:

import javax.swing.*; 

public class OptionDemo { 
    public static void main(String[] args) throws Exception { 
     JOptionPane.showMessageDialog(null, "Hello World"); 
    } 
} 

Me temo que no puedo explicar el retraso que estás experimentando. En mi sistema, su fragmento de código se ejecuta en 500 milisegundos.

+0

Esto parece aproximadamente la misma velocidad que el ejemplo AWT que probé (más de un segundo, tal vez alrededor de 1.5 s), lo que es una mejora, pero aún molestamente lento. Si podría llegar a 500ms que podría ser aceptable. –

1

podría utilizar el JOptionDialog

JOptionPane.showMessageDialog([parent frame], [message], [title], JOptionPane.MESSAGE_TYPE); 
3

Java es la herramienta equivocada para esto. La configuración de JVM implica muchas cosas sucediendo en segundo plano antes de que se pueda ejecutar la primera línea de código Java, y realmente no hay forma de evitarlo.

+0

Si la JVM es la causa, ¿por qué no es lenta cuando se envía a la consola a través de System.out.println ('Text')? –

+3

@ Peter: Porque la JVM no inicializa el subsistema AWT si no es necesario. Es más probable que eso esté causando la demora en este caso. –

10

La razón del retraso es debido a que Java es un lenguaje interpretado y se necesita tiempo para iniciar una nueva máquina virtual Java (el intérprete)

En realidad la creación del marco tarda menos de unos pocos ms (unos 70 ms en mi máquina)

Si esto se va a utilizar en una aplicación Java, no tiene que preocuparse por ello. Será casi instantáneo (debe usar JDialog o JOptionPane para esto)

Si esto NO se va a utilizar dentro de una aplicación Java, y 2 segundos es demasiado (y creo que es demasiado), debería considerar otra herramienta para el trabajo.

He aquí cómo medir el tiempo en el código:

import javax.swing.JFrame; 

public class Dialog { 

    public static void main(String[] args) { 
     long start = System.currentTimeMillis(); 
     JFrame frame = new JFrame("DialogDemo"); 
     System.out.println("Took: " + ( System.currentTimeMillis() - start )); 
    } 

} 
+0

Hmmm, usar tu código toma un promedio de 1460 ms aquí - eso es mucho más lento que tus 70ms - entonces debe haber algo mal con mi configuración? Este fragmento de código específico podría usar un script de shell, pero aún me gustaría saber por qué obtengo un rendimiento tan malo en comparación con usted u otros. –

+0

Toma aproximadamente de 400 a 500 ms en mi máquina (Pentium 3 M de 4 años con 1,8 GHz). – Bombe

+0

Los 70 ms transcurren entre el "inicio prolongado ..." y el System.out ... (exactamente como se imprimió en la prueba) Desde la consola se tarda aproximadamente 1,5 segundos. pero de nuevo, ese es el inicio de JVM. Desde una aplicación Java, no obtienes ese 1.5 extra. – OscarRyz

0

Ha intentado ejecutarlo a través de un generador de perfiles como NetBeans? Si hay un cuello de botella en el interior de la biblioteca estándar, esa es una buena forma de encontrarlo.

2

¿NECESITA usar java para mostrar el cuadro de mensaje? SI la caja proviene de fuera de su aplicación, entonces quizás quiera usar algo más para generar un diálogo.

Para hacer que una aplicación de Windows nativa que solo muestra un cuadro de mensaje desde una cadena de línea de comandos solo tome unas pocas horas como máximo. La mayoría de los lenguajes de scripting comunes también deberían tener formas de hacerlo. he aquí un ejemplo de un tipo a través de JavaScript a través de línea de comandos:

http://www.snee.com/bobdc.blog/2009/01/displaying-a-message-box-from.html

1

Puesto que usted está interesado en acelerar esto, y dado que la mayor parte de los gastos generales parece ser JVM sobrecarga de arranque, echa un vistazo a Nailgun que tiene como objetivo solucione el inicio de JVM lento manteniendo una JVM ejecutándose en segundo plano todo el tiempo. En su caso, después de una ejecución, la biblioteca Swing también terminará en caché (y con suerte después de algunas ejecuciones JIT también), reduciendo aún más la sobrecarga.

Sin embargo, este enfoque dará lugar a un mayor uso de memoria debido a la JVM de fondo y también causará otros problemas, ya que puede no ser fácil determinar cuándo apagarlo.

+0

Vea también goteo https://github.com/flatland/drip – rogerdpack

Cuestiones relacionadas