tutorial - manual de java swing en español
El componente de la pestaña JTabbedPane cambia el tamaño para adaptarse (2)
¿Hay un Look & Feel que tenga esta capacidad de "ajuste de pestaña"?
No conozco ninguno, pero puede publicar una ilustración para otros que hayan visto algo similar. Como el aspecto está controlado por el delegado de IU de L & F, TabbedPaneUI
, debe buscar una implementación existente o una de las subclases de uno de sus descendientes: BasicTabbedPaneUI
o MetalTabbedPaneUI
.
Quiero que mis etiquetas compartan el ancho de JTabbedPane. Si hay una sola pestaña, ajuste todo el ancho, si dos pestañas, comparten ancho, si son tres, 1/3 para cada uno y así sucesivamente ...
Ni siquiera sé si es posible hacerlo sin poner un componente allí y cambiar su tamaño, tal vez JTabbedPane tiene una forma de cambiar el tamaño de la etiqueta de su pestaña a través del método y no sé ...
¿Alguien tiene alguna idea de cómo hacerlo de la manera más fácil posible?
Como ya se mencionó en @trashgod, el diseño de pestañas se maneja mediante SomeLAFTabbedPaneUI específico de LAF, más específicamente, TabbedPaneLayout. Entonces, el camino a seguir es
- Implementar una subclase personalizada MySomeLAFTabbedPaneUI que tiene un TabbedPaneLayout extendido personalizado (debe hacer eso por cada SomeLAF que desee apoyar
- reemplaza el ui normal por tu clase personalizada
La primera se reduce para engancharse en el cálculo de los rectángulos que se utilizan para pintar las pestañas / localizar tabComponents personalizados. Algo así como (nota: obviamente no está listo para producción :-)
public class XMetalTabbedPaneUI extends MetalTabbedPaneUI {
public static ComponentUI createUI(JComponent c) {
return new XMetalTabbedPaneUI();
}
@Override
protected LayoutManager createLayoutManager() {
return new XTabbedPaneLayout();
}
protected class XTabbedPaneLayout extends MetalTabbedPaneUI.TabbedPaneLayout {
protected Container tabContainer;
@Override
protected void calculateTabRects(int tabPlacement, int tabCount) {
super.calculateTabRects(tabPlacement, tabCount);
// TODO: check if it makes sense to stretch
int max = 0;
int sum = 0;
Rectangle r = new Rectangle();
for (int i = 0; i < tabCount; i++) {
getTabBounds(i, r);
max = Math.max(max, r.width);
sum += r.width;
}
// TODO: calculate real width, that is -insets
int paneWidth = tabPane.getWidth() - 10;
int free = paneWidth - sum;
// nothing to distribute
if (free < tabCount) return;
int add = free /tabCount;
int offset = 0;
for (int i = 0; i < tabCount; i++) {
r = rects[i];
r.x += offset;
r.width += add;
offset += add;
}
}
}
}
El segundo es muy simplificado (me sesgo, como el mantenedor del proyecto :-) por el mecanismo de mejora plaf proporcionado por SwingX (en realidad, todo lo que necesita es su módulo plaf y dependencias). Su elemento básico es un TabbedPaneAddon que carga la interfaz de usuario personalizada:
public class TabbedPaneAddon extends AbstractComponentAddon {
/**
* @param name
*/
public TabbedPaneAddon() {
super("TabbedPane");
}
@Override
protected void addMetalDefaults(LookAndFeelAddons addon,
DefaultsList defaults) {
// remove old ui
UIManager.getLookAndFeelDefaults().put("TabbedPaneUI", null);
defaults.add("TabbedPaneUI",
// here goes the full classname of your custom ui
// this is an example only :-)
"org.jdesktop.swingx.XMetalTabbedPaneUI");
}
// implement other addXXDefault as needed for
// supporting more LAFs
}
Para que el reemplazo ocurra, debe contribuir con el complemento ("temprano") en su aplicación:
LookAndFeelAddons.contribute(new TabbedPaneAddon());