2011-10-22 28 views
8

Quiero personalizar el aspecto de las pestañas en JTabbedPane.
Quiero comenzar desde el comportamiento más simple y sencillo: sin bordes, color sólido.
El problema es que aún no se muestra una apariencia: las pestañas se superponen ligeramente.
JTabbedPane personalizar pestaña buscar

enter image description here

ves que ya se ha seleccionado la segunda pestaña, se "puso en primer plano". Esto se logra mediante una ligera superposición de margen. ¿Existe alguna forma (no engañosa) de deshabilitar este comportamiento?

sencilla, comprobable (basta con corregir las importaciones) Código:

public class TabbedPane_LookStudy extends JFrame{ 

public static void main(String [] args) throws UnsupportedLookAndFeelException { 
    UIManager.setLookAndFeel(new NimbusLookAndFeel()); 
    new TabbedPane_LookStudy().setVisible(true); 
} 

public TabbedPane_LookStudy() { 
    JTabbedPane tp = new JTabbedPane(); 
    tp.setUI(new MyTabbedPaneUI()); 
    add(tp); 

    tp.addTab("first",new JPanel()); 
    tp.addTab("second", new JPanel()); 
    tp.addTab("third", new JPanel()); 

    setPreferredSize(new Dimension(180,100)); 
    pack(); 
} 

public static class MyTabbedPaneUI extends javax.swing.plaf.basic.BasicTabbedPaneUI { 

    @Override 
    protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, 
       int tabIndex, Rectangle iconRect, Rectangle textRect) { 
     Color savedColor = g.getColor(); 
     g.setColor(Color.PINK); 
     g.fillRect(rects[tabIndex].x, rects[tabIndex].y, 
       rects[tabIndex].width, rects[tabIndex].height); 
     g.setColor(Color.BLUE); 
     g.drawRect(rects[tabIndex].x, rects[tabIndex].y, 
       rects[tabIndex].width, rects[tabIndex].height); 
     g.setColor(savedColor); 
    } 
} 

}

+0

+1 imagen, sscce, cuestionar – mKorbel

Respuesta

4

manera correcta sería la de poner en práctica Custom Look & Feel solamente. Pero si quieres jugar con XxxTabbedPaneUI, entonces tal vez this post te puede ayudar con eso.

para Nimbus será mejor para comprobar aephyr código de depósito

+0

empecé a ese puesto. Pero en esa implementación de UI, solo hay métodos paintXXX y calcula TabWidth y calcule TabHeight y NO colocación de pestañas.Así que pensé que la lógica de colocación de pestañas debe estar contenida en otra parte. – AgostinoX

+0

¿Qué es 'NO colocación de pestañas' que puede pintar desde la parte superior a través del borde (s) ... hasta la parte inferior, el borde de la pestaña está en la parte superior? – mKorbel

+0

lo siento, mKorbel, no lo entiendo. ¿podrías parafrasear? – AgostinoX

1

Puede anular paintContentBorderTopEdge en MyTabbedPaneUI de manera que no cree cualquiera de las fichas son seleccionados. Esto no es una solución bastante, pero la piratería clases de interfaz de usuario rara vez se presta a una en mi experiencia :)

@Override 
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, 
         int selectedIndex, int x, int y, int w, int h) { 
    super.paintContentBorderTopEdge(g, tabPlacement, -1, x, y, w, h); 
} 
2

La primera solución (parcial). He localizado el código de "posicionamiento".
Es el método calculateTabRects en TabbedPaneLayout, una clase interna de BasicTabbedPaneUI. El método es extremadamente complejo, pero lo bueno es que la parte que "plantea al frente" la pestaña está bien comentada y aislada en su propio método invaluable. Es padSelectedTab.

Crear una clase que no hace nada en lugar de elevar el componente es tan simple como:

protected class MyTabbedPaneLayout extends TabbedPaneLayout { 
     @Override 
     protected void padSelectedTab(int tabPlacement, int selectedIndex) { 
      //do nothing! 
      //super.padSelectedTab(tabPlacement, selectedIndex); 
     } 
    } 

en cuenta que tiene que ser una clase interna de MyTabbedPane. Tiene que ser una instancia anulando MyTabbedPane.createLayoutManager:

@Override 
    protected LayoutManager createLayoutManager() { 
     //return super.createLayoutManager(); 
     return new MyTabbedPaneLayout(); 
    } 

muy fácil y realmente funciona ... a excepción de un caso. createLayoutManager crea una instancia de TabbedPaneLayout si tabLayoutPolicy es WRAP_TAB_LAYOUT, pero crea una instancia de TabbedPanelScrollLayout si tabLayoutPolicy es SCROLL_TAB_LAYOUT. Este último tiene privado y no tiene acceso protegido, por lo que no es posible la subclase!
La implementación de mi createLayoutManager pierde el comportamiento de desplazamiento.

1

Usted puede poner las etiquetas HTML en el primer parámetro de la siguiente manera:

MyJTabbedPane.addTab("<html><h1 style='padding:20px;'>TEST</h1></html>", new JPanel());

Cuestiones relacionadas