2009-03-06 20 views
7

Actualmente estoy tratando de implementar un componente Swing, heredando de JLabel, que simplemente debe representar una etiqueta que se puede orientar verticalmente.Girar un Swing JLabel

A partir de esto:

public class RotatedLabel extends JLabel { 

    public enum Direction { 
    HORIZONTAL, 
    VERTICAL_UP, 
    VERTICAL_DOWN 
    } 

    private Direction direction; 

pensé que es ser una buena idea para simplemente alterar los resultados de getPreferredSize():

@Override 
    public Dimension getPreferredSize() { 
    // swap size for vertical alignments 
    switch (getDirection()) { 
    case VERTICAL_UP: 
    case VERTICAL_DOWN: 
     return new Dimension(super.getPreferredSize().height, super 
      .getPreferredSize().width); 
    default: 
     return super.getPreferredSize(); 
    } 
    } 

y luego simplemente transformar el objeto Graphics antes de la descarga de la pintura a la original JLabel:

@Override 
    protected void paintComponent(Graphics g) { 
    Graphics2D gr = (Graphics2D) g.create(); 

    switch (getDirection()) { 
    case VERTICAL_UP: 
     gr.translate(0, getPreferredSize().getHeight()); 
     gr.transform(AffineTransform.getQuadrantRotateInstance(-1)); 
     break; 
    case VERTICAL_DOWN: 
     // TODO 
     break; 
    default: 
    } 

    super.paintComponent(gr); 
    } 
} 

Parece que funciona, de alguna manera, porque ahora el texto se muestra verticalmente. Sin embargo, la ubicación y el tamaño están desactivados:

En realidad, el ancho del fondo (naranja en este caso) es idéntico a la altura del JFrame circundante, que no es exactamente lo que tenía en mente.

¿Alguna idea de cómo resolverlo de forma adecuada? ¿Se recomienda incluso delegar la representación en superclases?

+0

perdido "(" en 'gr.translate0, getPreferredSize(). GetHeight());' – brownian

Respuesta

8

Lo tengo para trabajar ahora con un poco de ayuda de un compañero de trabajo. Básicamente ahora tengo un campo que indica si se debe cambiar el alto/ancho, que solo está activo para el momento en que el original JLabel hace su pintura.

private boolean needsRotate; 

@Override 
public Dimension getSize() { 
    if (!needsRotate) { 
    return super.getSize(); 
    } 

    Dimension size = super.getSize(); 

    switch (getDirection()) { 
    case VERTICAL_DOWN: 
    case VERTICAL_UP: 
     return new Dimension(size.height, size.width); 
    default: 
    return super.getSize(); 
    } 
} 

@Override 
public int getHeight() { 
    return getSize().height; 
} 

@Override 
public int getWidth() { 
    return getSize().width; 
} 

@Override 
protected void paintComponent(Graphics g) { 
    Graphics2D gr = (Graphics2D) g.create(); 

    switch (getDirection()) { 
    case VERTICAL_UP: 
    gr.translate(0, getSize().getHeight()); 
    gr.transform(AffineTransform.getQuadrantRotateInstance(-1)); 
    break; 
    case VERTICAL_DOWN: 
    gr.transform(AffineTransform.getQuadrantRotateInstance(1)); 
    gr.translate(0, -getSize().getWidth()); 
    break; 
    default: 
    } 

    needsRotate = true; 
    super.paintComponent(gr); 
    needsRotate = false; 
} 
+0

¿Podría proporcionar la clase completa? –

+1

Ver http://hypftier.de/dump/RotatedLabel.java: la licencia mencionada es bastante liberal, siguiendo el modelo del BSD (aunque el texto de la licencia solo está disponible en alemán hasta el momento). – Joey

0

Creo que está apagado porque está traduciendo el punto equivocado.

el tamaño del objeto depende de en qué contenedor lo tenga, por lo tanto, aunque su tamaño preferido sea el que desea, ¿no es su tamaño real?

si tiene esta etiqueta en el centro de un BorderLayout, el tamaño es siempre el mismo tamaño del contenedor (menos del Norte + alto al sur, al este, menos ancho + oeste)

por lo que no hay que traducir sobre el tamaño real, el tamaño no preferido?

+0

Hmm ... no ... bastante. La colocación está un poco desajustada porque la alineación vertical de la etiqueta (ahora horizontal) está centrada, pero ahora el tamaño es exactamente cuadrado. ¿Podría ser que a la superclase no le importe mi método anulado GetPreferredSize y, por lo tanto, se dibuja a sí mismo no con respecto a mis límites? – Joey

2

He tenido una jugada con esto, inicialmente no funcionaba muy bien porque los límites de la etiqueta eran exactamente cuadrados y causaban que los componentes a la derecha de la etiqueta se desplazaran y se oscurecieran. Pero luego me di cuenta de que era porque estoy usando JGoodies FormLayout. Si usa este administrador de diseño, asegúrese de establecer el tamaño de columna en "preferido" y no "predeterminado". HTH.