El uso de múltiples JFrames: ¿buenas o malas prácticas?

Estoy desarrollando una aplicación que muestra imágenes y reproduce sonidos de una base de datos. Estoy tratando de decidir si usar o no un JFrame separado para agregar imágenes a la base de datos desde la GUI.

Me pregunto si es una buena práctica usar múltiples ventanas de JFrame.

Me pregunto si es una buena práctica usar múltiples JFrames.

Mala (mala, mala) práctica.

  • Usuario antipático: el usuario ve varios icons en su barra de tareas cuando espera ver solo uno. Además de los efectos secundarios de los problemas de encoding.
  • Una pesadilla para codificar y mantener:
    • Un diálogo modal ofrece la oportunidad fácil de centrar la atención en el contenido de ese diálogo: elija / corrija / cancele esto, luego proceda. Múltiples marcos no.
    • Un diálogo (o barra de herramientas flotante) con un padre aparecerá en el frente cuando se haga clic en el padre: deberá implementarlo en marcos si ese fue el comportamiento deseado.

Hay varias maneras de mostrar muchos elementos en una GUI, por ejemplo:

  • CardLayout ( demostración corta). Bueno para:
    1. Mostrando cuadros de diálogo tipo asistente.
    2. Visualización de selecciones de listas, árboles, etc. para elementos que tienen un componente asociado.
    3. Alternar entre ningún componente y componente visible.
  • JInternalFrame / JDesktopPane normalmente se utiliza para un MDI .
  • JTabbedPane para grupos de componentes.
  • JSplitPane Una forma de mostrar dos componentes cuya importancia entre uno y otro (el tamaño) varía de acuerdo con lo que el usuario está haciendo.
  • JLayeredPane ahora muchos componentes bien … de capas.
  • JToolBar normalmente contiene grupos de acciones o controles. Se puede arrastrar alrededor de la GUI o desactivarla por completo según las necesidades del usuario. Como se mencionó anteriormente, se minimizará / restaurará de acuerdo con el padre que lo haga.
  • Como elementos en una lista JList (ejemplo simple a continuación).
  • Como nodos en un JTree .
  • Diseños nesteds

Pero si esas estrategias no funcionan para un caso de uso en particular, intente lo siguiente. Establezca un solo JFrame principal, luego, JDialog instancias de JDialog o JOptionPane aparezcan para el rest de los elementos flotantes, usando el marco como el elemento principal para los cuadros de diálogo.

Muchas imágenes

En este caso donde los elementos múltiples son imágenes, sería mejor usar cualquiera de los siguientes en su lugar:

  1. Un solo JLabel (centrado en un panel de desplazamiento) para mostrar la imagen que al usuario le interese en ese momento. Como se ve en ImageViewer .
  2. Una sola fila JList . Como se ve en esta respuesta . La parte ‘sola fila’ de eso solo funciona si tienen todas las mismas dimensiones. Alternativamente, si está preparado para escalar las imágenes sobre la marcha, y todas tienen la misma relación de aspecto (por ejemplo, 4: 3 o 16: 9).

El enfoque múltiple de JFrame ha sido algo que he implementado desde que comencé a progtwigr aplicaciones Swing. En su mayor parte, lo hice al principio porque no sabía nada mejor. Sin embargo , a medida que maduré en mi experiencia y conocimiento como desarrollador y comencé a leer ya absorber las opiniones de tantos desarrolladores de Java más experimentados en línea, intenté alejarme del enfoque múltiple de JFrame (tanto en proyectos actuales como futuros proyectos) solo para cumplir con … obtener esto … ¡ resistencia de mis clientes! A medida que comencé a implementar diálogos modales para controlar ventanas “secundarias” y JInternalFrame s para componentes separados, ¡ mis clientes comenzaron a quejarse! ¡Estaba bastante sorprendido, ya que estaba haciendo lo que yo pensaba que era la mejor práctica! Pero, como dicen, “una esposa feliz es una vida feliz”. Lo mismo aplica para sus clientes. Por supuesto, soy un contratista para que mis usuarios finales tengan acceso directo a mí, el desarrollador, que obviamente no es un escenario común.

Por lo tanto, explicaré los beneficios del enfoque de JFrame múltiple, así como algunos de los inconvenientes que otros han presentado.

  1. Máxima flexibilidad en el diseño : al permitir JFrame separados, le da a su usuario final la capacidad de dispersarse y controlar lo que está en su pantalla. El concepto se siente “abierto” y no constrictivo. JInternalFrame esto cuando vas hacia un gran JFrame y un grupo de JInternalFrame s.
  2. Funciona bien para aplicaciones muy modularizadas : en mi caso, la mayoría de mis aplicaciones tienen de 3 a 5 grandes “módulos” que realmente no tienen nada que ver entre sí. Por ejemplo, un módulo podría ser un panel de ventas y uno podría ser un panel de contabilidad. No hablan entre ellos ni nada. Sin embargo, es posible que el ejecutivo desee abrir ambos y que al ser marcos separados en la barra de tareas, haga su vida más fácil.
  3. Facilita a los usuarios finales la referencia del material externo : una vez tuve esta situación: mi aplicación tenía un “visor de datos”, desde el que podía hacer clic en “Agregar nuevo” y abrir una pantalla de ingreso de datos. Inicialmente, ambos eran JFrame s. Sin embargo, quería que la pantalla de entrada de datos fuera un JDialog cuyo padre era el visor de datos. Hice el cambio, e inmediatamente recibí una llamada de un usuario final que confiaba mucho en el hecho de que podía minimizar o cerrar el visor y mantener abierto el editor mientras hacía referencia a otra parte del progtwig (o un sitio web, yo don no lo recuerdo). No está en un monitor múltiple, por lo que necesitaba el diálogo de entrada para ser el primero y otra cosa para ser el segundo, con el visor de datos completamente oculto. Esto fue imposible con un JDialog y ciertamente hubiera sido imposible con un JInternalFrame también. A regañadientes lo cambié de nuevo a JFrames por su cordura, pero me enseñó una importante lección.
  4. Mito: difícil de codificar : esto no es verdad en mi experiencia. No veo por qué sería más fácil crear un JInternalFrame que un JFrame . De hecho, en mi experiencia, JInternalFrames ofrece mucha menos flexibilidad. He desarrollado una forma sistemática de manejar la apertura y cierre de JFrame en mis aplicaciones que realmente funciona bien. Yo controlo el cuadro casi por completo desde dentro del código del marco; la creación del nuevo marco, SwingWorker s que controla la recuperación de datos en hilos de fondo y el código GUI en EDT, restaurar / traer al frente el marco si el usuario intenta abrirlo dos veces, etc. Todo lo que necesita para abrir mi JFrame s es llamar a un método público estático open() y el método abierto, combinado con un evento windowClosing() maneja el rest (¿el marco ya está abierto? ¿no está abierto, pero cargando? etc.) hice este enfoque una plantilla no es difícil de implementar para cada cuadro.
  5. Mito / No comprobado: Recurso pesado : me gustaría ver algunos hechos detrás de esta statement especulativa. Aunque, quizás, podría decir que un JFrame necesita más espacio que un JInternalFrame , incluso si abre 100 JFrame , ¿cuántos recursos más estaría consumiendo realmente? Si su preocupación es la pérdida de memoria debido a los recursos: llamar a dispose() libera todos los recursos utilizados por el marco para la recolección de basura (y, repito, un JInternalFrame debería invocar exactamente la misma preocupación).

He escrito mucho y siento que podría escribir más. De todos modos, espero no ser rechazado, votado simplemente porque es una opinión impopular. La pregunta es claramente valiosa y espero haber proporcionado una respuesta valiosa, incluso si no es la opinión común.

Un gran ejemplo de marcos múltiples / documento único por marco ( SDI ) frente a marco único / documentos múltiples por marco ( MDI ) es Microsoft Excel. Algunos de los beneficios de MDI:

  • es posible tener algunas ventanas en forma no rectangular, por lo que no ocultan el escritorio u otra ventana de otro proceso (por ejemplo, el navegador web)
  • es posible abrir una ventana desde otro proceso sobre una ventana de Excel mientras se escribe en la segunda ventana de Excel – con MDI, tratar de escribir en una de las ventanas internas dará enfoque a toda la ventana de Excel, por lo tanto, ocultando la ventana de otro proceso
  • es posible tener diferentes documentos en diferentes pantallas, lo que es especialmente útil cuando las pantallas no tienen la misma resolución

SDI (Interfaz de un solo documento, es decir, cada ventana solo puede tener un solo documento):

enter image description here

MDI (Interfaz de varios documentos, es decir, cada ventana puede tener múltiples documentos):

enter image description here

Me gustaría contrarrestar el argumento de “no fácil de usar” con un ejemplo en el que he estado involucrado.

En nuestra aplicación, tenemos una ventana principal donde los usuarios ejecutan varios ‘progtwigs’ como tabs separadas. En la medida de lo posible, hemos intentado mantener nuestra aplicación en esta única ventana.

Uno de los “progtwigs” que ejecutan presenta una lista de informes generados por el sistema, y ​​el usuario puede hacer clic en un icono en cada línea para abrir un cuadro de diálogo del visor de informes. Este visor muestra el equivalente de las páginas A4 de retrato / paisaje del informe, por lo que a los usuarios les gusta que esta ventana sea bastante grande y casi llena sus pantallas.

Hace unos meses, comenzamos a recibir solicitudes de nuestros clientes para que estas ventanas de visor de informes no tuvieran ningún tipo de efecto, de modo que pudieran tener varios informes abiertos al mismo tiempo.

Durante un tiempo me resistí a esta solicitud ya que no creía que esta fuera una buena solución. Sin embargo, mi mente cambió cuando descubrí cómo los usuarios estaban solucionando esta “deficiencia” de nuestro sistema.

Estaban abriendo un visor, utilizando la función ‘Guardar como’ para guardar el informe como un PDF en un directorio específico, usando Acrobat Reader para abrir el archivo PDF, y luego harían lo mismo con el próximo informe. Tendrían varios lectores Acrobat funcionando con los diversos resultados del informe que querían ver.

Así que cedí e hice al espectador no modal. Esto significa que cada espectador tiene un ícono de barra de tareas.

Cuando se les dio a conocer la última versión la semana pasada, la respuesta abrumadora de ellos es que les ENCANTA. Ha sido una de nuestras mejoras recientes más populares al sistema.

Así que sigue y dile a tus usuarios que lo que quieren es malo, pero que en última instancia no te hará ningún favor.

ALGUNAS NOTAS:

  • Parece ser la mejor práctica usar JDialog para estas ventanas sin modelaje
  • Utilice los constructores que usan el nuevo ModalityType lugar del argumento modal booleano. Esto es lo que le da a estos cuadros de diálogo el ícono de la barra de tareas.
  • Para los cuadros de diálogo no modal, pase un elemento primario nulo al constructor, pero ubíquelos en relación con su ventana “principal”.
  • La versión 6 de Java en Windows tiene un error que significa que su ventana principal puede convertirse en ‘siempre en la parte superior’ sin que usted lo cuente. Actualice a la versión 7 para arreglar esto

Haz un jInternalFrame en el marco principal y hazlo invisible. Entonces puedes usarlo para otros eventos.

 jInternalFrame.setSize(300,150); jInternalFrame.setVisible(true); 

Ha pasado un tiempo desde la última vez que toco el swing, pero en general es una mala práctica para hacer esto. Algunas de las principales desventajas que viene a la mente:

  • Es más costoso: tendrá que asignar más recursos para dibujar un JFrame que otro tipo de contenedor de ventana, como Dialog o JInternalFrame.

  • No es fácil de usar: no es fácil navegar dentro de un montón de JFrame unidos, parecerá que su aplicación es un conjunto de aplicaciones inconsistentes y de diseño deficiente.

  • Es fácil de utilizar JInternalFrame Esto es un poco retorico, ahora es mucho más fácil y otras personas más inteligentes (o con más tiempo libre) que nosotros ya pensamos en el diseño de escritorio y JInternalFrame, por lo que recomendaría usarlo.

Mala práctica definitivamente. Una razón es que no es muy fácil de usar por el hecho de que cada JFrame muestra un nuevo ícono en la barra de tareas. Controlar múltiples JFrame hará que te rasgues el pelo.

Personalmente, usaría ONE JFrame para su tipo de aplicación. Los métodos para mostrar múltiples cosas depende de usted, hay muchos. Canvas es, JInternalFrame , CardLayout , incluso JPanel posiblemente.

Múltiples objetos JFrame = dolor, problemas y problemas.

Creo que usar múltiples Jframe no es una buena idea.

En su lugar, podemos usar JPanel más de uno o más JPanel en el mismo JFrame .

También podemos cambiar entre este JPanel s. Por lo tanto, nos da libertad para mostrar más que en una cosa en el JFrame .

Para cada JPanel podemos diseñar diferentes cosas y todo esto JPanel se puede mostrar en el único JFrame a una por vez.

Para alternar entre este JPanel , use JMenuBar con JMenuItems para cada JPanel o ‘JButton for each JPanel`.

Más de un JFrame no es una buena práctica, pero no hay nada de malo si queremos más de un JFrame .

Pero es mejor cambiar un JFrame para nuestras diferentes necesidades en lugar de tener múltiples JFrame .

Si los marcos van a tener el mismo tamaño, ¿por qué no crear el cuadro y pasar el cuadro como referencia en su lugar?

Cuando haya pasado el marco, podrá decidir cómo poblarlo. Sería como tener un método para calcular el promedio de un conjunto de figuras. ¿Crearías el método una y otra vez?

No es una buena práctica pero, aunque desee usarla, puede usar el patrón singleton como bueno. He utilizado los patrones de singleton en la mayor parte de mi proyecto es bueno.