Varias veces me han criticado por haber sugerido el uso de los siguientes métodos:
- setPreferredSize
- setMinimumSize
- setMaximumSize
en Swing
componentes. No veo ninguna alternativa a su uso cuando quiero definir proporciones entre los componentes mostrados. Me han dicho esto:
Con los diseños, la respuesta es siempre la misma: use un LayoutManager adecuado
He buscado un poco en la web, pero no he encontrado ningún análisis exhaustivo del tema. Entonces tengo las siguientes preguntas:
- ¿Debo evitar por completo el uso de esos métodos?
- Los métodos han sido definidos por una razón. Entonces, ¿cuándo debo usarlos? ¿En que contexto? ¿Para que fines?
- ¿Cuáles son exactamente las consecuencias negativas de usar esos métodos? (Solo puedo pensar en agregar portabilidad entre sistemas con diferente resolución de pantalla).
- No creo que ningún LayoutManager pueda satisfacer exactamente todas las necesidades de diseño deseadas. ¿Realmente necesito implementar un nuevo LayoutManager para cada pequeña variación en mi diseño?
- Si la respuesta a 4 es "sí", ¿esto no conducirá a una proliferación de clases LayoutManager que será difícil de mantener?
- En una situación en la que necesito definir proporciones entre los hijos de un Componente (p. Ej., Child1 debería usar el 10% del espacio, child2 40%, child3 50%), ¿es posible lograrlo sin implementar un LayoutManager personalizado?
fuente
JEditorPane
con HTML que no sugiere por sí mismo un ancho. OTOH No estoy seguro si me he perdido algo. Revisaré cuidadosamente las respuestas en el hilo, pero estaba interesado si tenía algún comentario, particularmente sobre el último caso.Algunas heurísticas:
No lo use
set[Preferred|Maximum|Minimum]Size()
cuando realmente quiera anularget[Preferred|Maximum|Minimum]Size()
, como podría hacerse al crear su propio componente, como se muestra aquí .No use
set[Preferred|Maximum|Minimum]Size()
cuando podría confiar en que un componente se anule cuidadosamentegetPreferred|Maximum|Minimum]Size
, como se muestra aquí y a continuación.Utilícelo
set[Preferred|Maximum|Minimum]Size()
para derivar lavalidate()
geometría posterior , como se muestra a continuación y aquí .Si un componente no tiene un tamaño preferido, por ejemplo
JDesktopPane
, puede que tenga que cambiar el tamaño del contenedor, pero cualquier elección es arbitraria. Un comentario puede ayudar a aclarar la intención.Considere diseños alternativos o personalizados cuando descubra que tendría que recorrer muchos componentes para obtener tamaños derivados, como se menciona en estos comentarios .
fuente
setPreferredSize()
siempre reemplaza el cálculo del componente con una elección arbitraria.No, no hay evidencia formal que sugiera que llamar o anular estos métodos no esté permitido. De hecho, Oracle dice que estos métodos se utilizan para dar pistas sobre el tamaño: http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment .
También pueden anularse (que es la mejor práctica para Swing) al extender un componente Swing (en lugar de llamar al método en la instancia del componente personalizado)
Lo más importante, independientemente de cómo especifique el tamaño de su componente, asegúrese de que el contenedor de su componente utilice un administrador de diseño que respete el tamaño solicitado del componente.
Cuando necesite proporcionar sugerencias de tamaño personalizadas al administrador de diseño de contenedores para que el componente se distribuya bien
Muchos administradores de diseño no prestan atención al tamaño máximo solicitado de un componente. Sin embargo,
BoxLayout
ySpringLayout
hacer. Además,GroupLayout
proporciona la capacidad de establecer el tamaño mínimo, preferido o máximo explícitamente, sin tocar el componente.Asegúrese de que realmente necesita establecer el tamaño exacto del componente. Cada componente Swing tiene un tamaño preferido diferente, dependiendo de la fuente que usa y el aspecto. Por lo tanto, tener un tamaño establecido puede producir una apariencia variada de la interfaz de usuario en diferentes sistemas
a veces se pueden encontrar problemas con
GridBagLayout
los campos de texto, en los que si el tamaño del contenedor es más pequeño que el tamaño preferido, se utiliza el tamaño mínimo, lo que puede hacer que los campos de texto se reduzcan considerablemente.JFrame
no impone anulacióngetMinimumSize()
solo invocandosetMinimumSize(..)
sus obrasSi por implementar te refieres a usar, entonces sí. No se
LayoutManger
puede manejar todo, cada unoLayoutManager
tiene sus pros y sus contras, por lo que se pueden usar juntos para producir el diseño final.Referencia:
fuente
setXxxSize
métodos como una señal de alerta que podría terminar aquí , incluso cuando los documentos lo sugieran. Yo casi siempre debería haber anuladogetXxxSize
, donde se tiene acceso a la geometría requerida; e incluso ejemplos cortos se reciclan más de lo que quiero pensar. +1 por mencionar la variación entre los administradores de diseño y citar el tutorial.Aquí hay muchas buenas respuestas, pero quiero agregar un poco más sobre las razones por las que normalmente debería evitarlas (la pregunta surgió nuevamente en un tema duplicado):
Con pocas excepciones, si está utilizando estos métodos, probablemente esté ajustando su GUI para que se vea bien en un aspecto específico (y con la configuración específica de su sistema, por ejemplo, su fuente de escritorio preferida, etc.). Los métodos en sí mismos no son intrínsecamente malos, pero las razones típicas para usarlos sí lo son . Tan pronto como comience a ajustar las posiciones y tamaños de píxeles en un diseño, corre el riesgo de que su GUI se rompa (o como mínimo, se vea mal), en otras plataformas.
Como ejemplo de esto, intente cambiar el aspecto predeterminado de su aplicación. Incluso solo con las opciones disponibles en su plataforma, puede sorprenderse de lo mal que se pueden presentar los resultados.
Entonces, en nombre de mantener su GUI funcional y agradable en todas las plataformas (recuerde, uno de los principales beneficios de Java es su multiplataforma), debe confiar en los administradores de diseño, etc., para ajustar automáticamente los tamaños de sus componentes para que se represente correctamente fuera de su entorno de desarrollo específico.
Dicho todo esto, ciertamente puede concebir situaciones en las que estos métodos estén justificados. Una vez más, no son intrínsecamente malvados, pero su uso es normalmente una gran señal de alerta que indica posibles problemas de GUI. Solo asegúrese de estar al tanto del alto potencial de complicaciones si / cuando las usa, y siempre trate de pensar si hay otra solución independiente de la apariencia y la sensación para sus problemas; la mayoría de las veces encontrará que estos Los métodos no son necesarios.
Por cierto, si te sientes frustrado con los administradores de diseño estándar, hay muchos otros buenos y gratuitos de código abierto de terceros, por ejemplo, JGoodies '
FormLayout
oMigLayout
. Algunos constructores de GUI incluso tienen soporte incorporado para administradores de diseño de terceros: el editor de GUI WindowBuilder de Eclipse, por ejemplo, se entrega con soporte paraFormLayout
yMigLayout
.fuente
JTextField.setColumns
para establecer el recuento de columnas, que ajusta el tamaño preferido en consecuencia. Si lo hace,setPreferredSize
entonces está codificando un tamaño, lo que romperá sus diseños según el tamaño de fuente de la plataforma. Aquí hay algunos campos de texto en un diseño de bolsa de cuadrícula consetColumns
llamadas apropiadas . Para sus botones, use diseños / pesos de cuadrícula apropiados para controlar los tamaños.Si tiene problemas con los diseños en Java Swing, le recomiendo encarecidamente los JGoodies
FormLayout
que Karsten Lentzsch proporciona gratuitamente como parte de la biblioteca gratuita de formularios de aquí .Este administrador de diseño muy popular es extremadamente flexible, lo que permite desarrollar interfaces de usuario Java muy pulidas.
Encontrará la documentación de Karsten aquí , y una documentación bastante buena de eclipse aquí .
fuente
Estos métodos son poco conocidos por la mayoría de las personas. No debes ignorar estos métodos. Depende del administrador de diseño si respetan estos métodos. Esta página tiene una tabla que muestra qué administradores de diseño respetan cuál de esos métodos:
http://thebadprogrammer.com/swing-layout-manager-sizing/
He estado escribiendo código Swing durante más de 8 años y los gerentes de diseño incluidos en el JDK siempre han respondido a mis necesidades. Nunca he necesitado un administrador de diseño de terceros para lograr mis diseños.
Diré que no debe tratar de dar pistas al administrador de diseño con estos métodos hasta que esté seguro de que los necesita. Realice su diseño sin dar ninguna sugerencia de tamaño (es decir, deje que el administrador de diseño haga su trabajo) y luego puede hacer correcciones menores si es necesario.
fuente
Quizás
GridBagLayout
satisfaría tus necesidades. Además de eso, hay un montón de administradores de diseño en la web, y apuesto a que hay uno que se ajusta a sus requisitos.fuente
Lo veo diferente a la respuesta aceptada.
1) ¿Debo evitar por completo el uso de esos métodos?
¡Nunca lo evites! Están allí para expresar las restricciones de tamaño de sus componentes al administrador de diseño. Puede evitar usarlos si no está usando ningún administrador de diseño e intente administrar el diseño visual por su cuenta.
Desafortunadamente, Swing no viene con dimensiones predeterminadas razonables. Sin embargo, en lugar de establecer las dimensiones de un componente, es mejor que OOP descienda su propio componente con valores predeterminados razonables. (En ese caso, llama a setXXX en su clase descendiente). Alternativamente, puede anular los métodos getXXX para obtener el mismo efecto.
2) Los métodos han sido definidos por una razón. Entonces, ¿cuándo debo usarlos? ¿En que contexto? ¿Para que fines?
Siempre. Cuando cree un componente, establezca su tamaño mínimo / preferido / máximo realista de acuerdo con el uso de ese componente. Por ejemplo, si tiene un JTextField para ingresar símbolos de país como el Reino Unido, su tamaño preferido será tan ancho como para caber dos caracteres (con la fuente actual, etc.) pero probablemente no tenga sentido dejar que crezca más. Después de todo, los símbolos de país son dos caracteres. Por el contrario, si tiene un JTextField para ingresar, por ejemplo, el nombre de un cliente, puede tener un tamaño preferido como el tamaño de píxel para 20 caracteres, pero puede crecer hasta ser más grande si se cambia el tamaño del diseño, así que configure el tamaño máximo en más. Al mismo tiempo, tener un JTextField de 0px de ancho no tiene sentido, así que establezca un tamaño mínimo realista (yo diría que el tamaño de píxel de 2 caracteres).
3) ¿Cuáles son exactamente las consecuencias negativas de usar esos métodos?
(Solo puedo pensar en agregar portabilidad entre sistemas con diferente resolución de pantalla).
Sin consecuencias negativas. Estas son sugerencias para el administrador de diseño.
4) No creo que ningún LayoutManager pueda satisfacer exactamente todas las necesidades de diseño deseadas.
¿Realmente necesito implementar un nuevo LayoutManager para cada pequeña variación en mi diseño?
No, definitivamente no. El enfoque habitual es poner en cascada diferentes gestores de diseño básicos, como el diseño horizontal y vertical.
Por ejemplo, el diseño a continuación:
tiene dos partes Las partes izquierda y derecha son un diseño horizontal. La parte derecha es un JPanel agregado al diseño horizontal, y este JPanel tiene un diseño vertical que presenta los botones verticalmente.
Por supuesto, esto puede volverse complicado con un diseño de la vida real. Por lo tanto, los administradores de diseño basados en cuadrícula como MigLayout son mucho mejores si está a punto de desarrollar algo serio.
5) Si la respuesta a 4 es "sí", ¿no dará lugar a una proliferación de clases LayoutManager que será difícil de mantener?
No, definitivamente no deberá desarrollar administradores de diseño, a menos que necesite algo muy especial.
6) En una situación en la que necesito definir proporciones ...
entre los hijos de un Componente (p. ej., child1 debería usar el 10% del espacio, child2 40%, child3 50%), ¿es posible lograr eso sin implementar un LayoutManager personalizado?
Básicamente, una vez que los tamaños preferidos se configuran correctamente, es posible que no desee hacer nada en porcentaje. Simplemente, porque los porcentajes no tienen sentido (por ejemplo, no tiene sentido tener un JTextField del 10% del tamaño de la ventana, ya que uno puede reducir la ventana para que JTextField tenga 0px de ancho, o puede expandir la ventana para que JTextField esté en dos pantallas en un configuración de pantallas múltiples).
Pero, muchas veces, puede usar los porcentajes para controlar los tamaños de los bloques de construcción más grandes de su interfaz gráfica de usuario (paneles, por ejemplo).
Puede usar JSplitPane donde puede preestablecer la relación de los dos lados. O bien, puede usar MigLayout, que le permite establecer tales restricciones en porcentaje, píxeles y otras unidades.
fuente
btnBar.setPreferredSize( dimTouchBtn );
Es la mejor manera de hacerlo. Directo, sin necesidad de un administrador de diseño personalizado. Utilizo principalmenteGridBagLayout
con algunosBorderLayout
yBoxLayout
, anidando cuando es conveniente. Esta es una combinación fuerte y fácil de usar.¿Debo evitar por completo el uso de esos métodos? Yo no diría "evitarlos". Diría que si crees que los necesitas, probablemente estés haciendo algo mal. Los tamaños de los componentes se determinan en contexto. Por ejemplo, los tamaños de los componentes de texto están determinados por la cantidad de filas y columnas que especifique, combinadas con la fuente que haya elegido. El tamaño de su botón y etiqueta será el tamaño del gráfico, si configura uno, o el espacio necesario para mostrar el texto que configuró. Cada componente tiene un tamaño natural, y los administradores de diseño los usarán para diseñar todo sin necesidad de especificar tamaños. La excepción principal es JScrollPane, que tiene un tamaño independiente de lo que contenga. Para aquellos, a veces llamaré
setSize()
, y dejaré que ese tamaño determine el tamaño inicial de la ventana, llamandoJFrame.pack()
. Por lo general, dejaré que el tamaño de la ventana determine el tamaño de JScrollPane. El usuario determinará el tamaño de la ventana. Muchos administradores de diseño ignoran los tamaños que configura de todos modos, por lo que a menudo no hacen mucho bien.Los métodos han sido definidos por una razón. Entonces, ¿cuándo debo usarlos? ¿En que contexto? ¿Para que fines? Creo que se agregaron para proporcionar pistas a los gerentes de diseño. Es posible que se hayan escrito por razones históricas, porque los administradores de diseño eran nuevos y la gente no confiaba plenamente en ellos. Conozco algunos desarrolladores que evitaron los administradores de diseño y colocaron todo manualmente, solo porque no querían molestarse en aprender un nuevo paradigma. Es una idea terrible.
¿Cuáles son exactamente las consecuencias negativas de usar esos métodos? (Solo puedo pensar en agregar portabilidad entre sistemas con diferente resolución de pantalla). Son ineficaces y producen diseños malos, con objetos que se exprimen o estiran a tamaños no naturales. Y los diseños serán frágiles. Los cambios en el tamaño de la ventana a veces rompen el diseño y colocan las cosas en los lugares equivocados.
No creo que ningún LayoutManager pueda satisfacer exactamente todas las necesidades de diseño deseadas. ¿Realmente necesito implementar un nuevo LayoutManager para cada pequeña variación en mi diseño? No debe "implementar" un nuevo LayoutManager. Debe crear instancias de las existentes. A menudo uso varios administradores de diseño en una sola ventana. Cada JPanel tendrá su propio administrador de diseño. Algunas personas se resisten a los diseños anidados, porque son difíciles de mantener. Cuando los uso, les doy a cada uno su propio método de creación para que sea más fácil ver lo que hace cada uno. Pero nunca "implemento" un administrador de diseño. Yo solo los instancia.
Si la respuesta a 4 es "sí", ¿no conducirá esto a una proliferación de clases LayoutManager que será difícil de mantener? Si está implementando nuevas clases de administrador de diseño para ligeras variaciones en el diseño, las está usando mal. Si solo está implementando nuevos administradores de diseño, probablemente esté haciendo algo mal. La única vez que extendí una clase de LayoutManager fue para agregar un control deslizante de zoom a un JScrollPane.
En una situación en la que necesito definir proporciones entre los hijos de un Componente (p. Ej., Child1 debería usar el 10% del espacio, child2 40%, child3 50%), ¿es posible lograrlo sin implementar un LayoutManager personalizado? JSplitPane tiene una forma de especificar el porcentaje que debe obtener cada componente. El divisor es móvil de forma predeterminada, pero puede desactivarlo si lo desea. No uso mucho esa función. Por lo general, tengo algunos componentes que ocupan un tamaño establecido, y el resto del espacio lo ocupa un panel de desplazamiento. El tamaño del panel de desplazamiento se ajustará con el tamaño de la ventana. Si tiene dos paneles de desplazamiento uno al lado del otro, puede colocarlos en un JSplitPane y especificar el porcentaje de espacio nuevo asignado a cada uno a medida que el usuario expande y contrae las ventanas.
fuente