Pregunta
Actualmente estoy tratando de implementar un componente Swing, heredando de JLabel
que simplemente debería representar una etiqueta que pueda orientarse verticalmente.
Comenzando con esto:
public class RotatedLabel extends JLabel {
public enum Direction {
HORIZONTAL,
VERTICAL_UP,
VERTICAL_DOWN
}
private Direction direction;
Pensé que sería una buena idea 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 transforma el objeto Graphics
antes de descargar la pintura al JLabel
original:
@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, en que el texto ahora 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 es ... no es exactamente lo que tenía en mente.
¿Alguna idea de cómo resolver eso de una manera adecuada? ¿Se alienta a delegar la representación en superclases?
Solución
Lo puse a trabajar ahora con un poco de ayuda de un compañero de trabajo. Básicamente, ahora tengo un campo que indica si intercambiar altura / anchura que solo está activa en el momento en que el JLabel
original 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;
}
Otros consejos
No sé si es relevante por ahora, Pero mientras buscaba lo mismo, encontré una muy buena implementación en la web, http://macdevcenter.com/pub/a/mac/2002 /03/22/vertical_text.html
Compruébalo, es una implementación sobre el Panel Tabbed con texto vertical, A ver si se ajusta a tus propósitos.
He jugado 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 movieran y se oscurecieran. Pero luego me di cuenta de que era porque estoy usando JGoodies FormLayout. Si utiliza este administrador de diseño, asegúrese de establecer el tamaño de la columna en "preferido". no " predeterminado " ;. HTH.
Creo que está apagado porque estás traduciendo sobre el punto incorrecto.
el tamaño del objeto depende del contenedor en el que tengas esto, por lo que si bien tu tamaño preferido podría ser el que deseas, tu tamaño real no lo es.
si tiene esta etiqueta en el CENTRO de un BorderLayout, el tamaño es siempre el tamaño completo del contenedor (menos la altura norte + sur, menos este + ancho oeste)
¿no tiene que traducir el tamaño real, no el tamaño preferido?