inside create java swing user-interface jframe

create - frame inside a frame java



El uso de múltiples JFrames: ¿Buenas o malas prácticas? (9)

Estoy desarrollando una aplicación que muestra imágenes y reproduce sonidos de una base de datos. Estoy intentando 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 práctica (mala, mala).

  • Usuario hostil: El usuario ve varios íconos en su barra de tareas cuando espera ver solo uno. Más los efectos secundarios de los problemas de codificación.
  • 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 / arreglar / cancelar esto, luego proceda. Los marcos múltiples no lo hacen.
    • Un cuadro de diálogo (o barra de herramientas flotante) con un padre aparecerá al frente cuando se haga clic en el padre: tendrá que implementarlo en marcos si ese fue el comportamiento deseado.

Hay muchas formas de mostrar muchos elementos en una GUI, por ejemplo:

  • CardLayout ( demo. corta). Bueno para:
    1. Mostrando asistente como diálogos.
    2. Visualización de selecciones de lista, árbol, etc. para elementos que tienen un componente asociado.
    3. Volteo 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 u otro (el tamaño) varía según lo que esté haciendo el usuario.
  • JLayeredPane lejos muchos componentes bien ... capas.
  • JToolBar normalmente contiene grupos de acciones o controles. Se puede arrastrar alrededor de la GUI, o desactivarla completamente según las necesidades del usuario. Como se mencionó anteriormente, minimizará / restaurará según lo haga el padre.
  • Como elementos en un JList (ejemplo simple más abajo).
  • Como nodos en un JTree .
  • Diseños anidados .

Pero si esas estrategias no funcionan para un caso de uso particular, intente lo siguiente. Establezca un único JFrame principal, luego JDialog aparezcan las instancias de JDialog o JOptionPane para el resto de los elementos flotantes, utilizando el marco como elemento primario para los diálogos.

Muchas imagenes

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

  1. Una sola JLabel (centrada en un panel de desplazamiento) para mostrar la imagen que le interesa al usuario en ese momento. Como se ve en ImageViewer .
  2. Una sola fila JList . Como se ve en esta respuesta . La parte de ''una sola fila'' solo funciona si todas tienen 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).

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

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

También podemos cambiar entre este JPanel s. Así que nos da libertad para mostrar más de lo que está en el JFrame .

Para cada JPanel podemos diseñar diferentes cosas y todo este JPanel se puede mostrar en un solo JFrame uno en uno.

Para cambiar entre este JPanel s 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 s.


El enfoque de JFrame múltiple ha sido algo que he implementado desde que comencé a programar aplicaciones Swing. En su mayor parte, lo hice al principio porque no conocía nada mejor. Sin embargo , a medida que maduré en mi experiencia y conocimiento como desarrollador y cuando comencé a leer y absorber las opiniones de muchos desarrolladores Java más experimentados en línea, hice un intento por alejarme del enfoque de JFrame múltiple (tanto en proyectos actuales como futuros). proyectos) solo para reunirse con ... obtener esta ... resistencia de mis clientes! Cuando comencé a implementar diálogos modales para controlar ventanas "secundarias" y JInternalFrame para componentes separados, ¡ mis clientes comenzaron a quejarse! Me sorprendió bastante, ya que estaba haciendo lo que creía que era la mejor práctica. Pero, como dicen, "Una esposa feliz es una vida feliz". Lo mismo ocurre con sus clientes. Por supuesto, soy un contratista, por lo que mis usuarios finales tienen acceso directo a mí, el desarrollador, lo que obviamente no es un escenario común.

Por lo tanto, voy a explicar los beneficios del enfoque de JFrame múltiple, así como el mito de 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 expandirse 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 montón de JInternalFrame s.
  2. Funciona bien para aplicaciones muy modulares . En mi caso, la mayoría de mis aplicaciones tienen 3 a 5 "módulos" grandes que realmente no tienen nada que ver entre ellos en absoluto. Por ejemplo, un módulo puede ser un panel de ventas y otro puede ser un panel de contabilidad. No se hablan ni nada. Sin embargo, el ejecutivo puede querer abrir ambos y, al ser marcos separados en la barra de tareas, le facilita la vida.
  3. Facilita a los usuarios finales hacer referencia al material externo . Una vez tuve esta situación: mi aplicación tenía un "visor de datos", desde el cual podía hacer clic en "Agregar nuevo" y se abría 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 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 programa (o un sitio web, no No recuerdo). No está en un monitor múltiple, por lo que necesitaba que el diálogo de entrada fuera el primero y otra cosa que lo segundo, con el visor de datos completamente oculto. Esto era imposible con un JDialog y ciertamente también hubiera sido imposible con un JInternalFrame . Cambié a regañadientes de nuevo a JFrames separados por su cordura, pero me enseñó una lección importante.
  4. Mito: difícil de codificar : esto no es cierto 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 s en mis aplicaciones que realmente funciona bien. Controlo el marco casi completamente desde dentro del propio código del marco; la creación del nuevo marco, SwingWorker s que controlan la recuperación de datos en subprocesos en segundo plano y el código GUI en EDT, restaurando / trayendo al frente el marco si el usuario intenta abrirlo dos veces, etc. Todo lo que necesita para abrir mi JFrame s es un método público estático open() y el método abierto, combinado con un evento windowClosing() se encarga del resto (¿el marco ya está abierto? ¿no está abierto, pero se está cargando? etc.). No es difícil de implementar para cada cuadro.
  5. Mito / no comprobado: gran cantidad de recursos : me gustaría ver algunos datos detrás de esta declaración 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, nuevamente, digo, 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 desestimado simplemente porque es una opinión impopular. La pregunta es claramente valiosa y espero haber brindado una respuesta valiosa, incluso si no es la opinión común.

Un excelente ejemplo de múltiples marcos / documento único por marco ( SDI ) frente a un solo marco / 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, un navegador web)
  • es posible abrir una ventana desde otro proceso a través de una ventana de Excel mientras se escribe en la segunda ventana de Excel; con MDI, intentar escribir en una de las ventanas internas dará prioridad a toda la ventana de Excel, por lo tanto, ocultará la ventana de otro proceso
  • Es posible tener diferentes documentos en diferentes pantallas, lo cual es especialmente útil cuando las pantallas no tienen la misma resolución.

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

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


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

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

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

  • Es fácil de usar JInternalFrame Esto es un poco retorical, ahora es mucho más fácil y otras personas más inteligentes (o con más tiempo libre) que nosotros ya hemos pensado en el patrón de Escritorio y JInternalFrame, por lo que recomendaría su uso.


Haz un marco interno en el marco principal y hazlo invisible. Luego puedes usarlo para otros eventos.

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


Mala práctica definitivamente. Una razón es que no es muy fácil de usar porque el JFrame muestra un nuevo icono de la barra de tareas. Controlar varios JFrame s te hará arrancarte el pelo.

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

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


Me gustaría contrarrestar el argumento "no fácil de usar" con un ejemplo en el que acabo de estar involucrado.

En nuestra aplicación tenemos una ventana principal donde los usuarios ejecutan varios ''programas'' como pestañas separadas. En la medida de lo posible, hemos intentado mantener nuestra aplicación en esta única ventana.

Uno de los ''programas'' 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 la (s) página (s) A4 vertical / horizontal del informe, por lo que a los usuarios les gusta que esta ventana sea bastante grande, casi llenando sus pantallas.

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

Durante un tiempo resistí 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 resolviendo esta "deficiencia" de nuestro sistema.

Estaban abriendo un visor, usando 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 siguiente informe. Tendrían múltiples lectores de Acrobat ejecutándose con los diversos resultados de informe que querían ver.

Así que me arrepentí e hice la espectadora sin modelo. Esto significa que cada espectador tiene un icono de barra de tareas.

Cuando se les lanzó 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 en el sistema.

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

ALGUNAS NOTAS:

  • Parece ser una buena práctica usar JDialog para estas ventanas sin modelo
  • 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 icono de la barra de tareas.
  • Para los diálogos sin modelo, 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 bug que significa que su ventana principal puede convertirse en "siempre arriba" sin que usted lo diga. Actualiza a la versión 7 para arreglar esto

No es una buena práctica, pero aunque desees usarlo, puedes usar el patrón de singleton como bueno. He usado los patrones singleton en la mayor parte de mi proyecto es bueno.


Si los marcos van a tener el mismo tamaño, ¿por qué no crear el marco y pasar el marco como una referencia a él?

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