Pergunta
Atualmente, estou tentando implementar um componente Swing, herdando de JLabel
que deve representar simplesmente um rótulo que pode ser orientada verticalmente.
Começando com esta:
public class RotatedLabel extends JLabel {
public enum Direction {
HORIZONTAL,
VERTICAL_UP,
VERTICAL_DOWN
}
private Direction direction;
Eu pensei que é ser uma idéia agradável para apenas alterar os 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();
}
}
e depois simplesmente transformar o objeto Graphics
antes de descarregar a pintura ao 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-trabalho-de alguma forma-in que o texto agora é exibido verticalmente. No entanto, a colocação eo tamanho estão desligados.
Na verdade, a largura do fundo (laranja, neste caso) é idêntica à altura do JFrame
circundante que é ... não é o que eu tinha em mente.
Todas as idéias como resolver isso de uma maneira adequada? É delegar prestação de superclasses mesmo incentivado?
Solução
Eu tenho que trabalhar agora com uma pequena ajuda de um colega de trabalho. Basicamente Agora tenho um campo que indica se a altura swap / largura, que só está ativo para o momento em que o JLabel
originais faz a sua 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;
}
Outras dicas
Eu não sei se é relevante até agora, Mas durante a pesquisa para a mesma coisa, eu encontrei um muito boa implementação na web, http://macdevcenter.com/pub/a/mac/2002 /03/22/vertical_text.html
Confira, é uma implementação sobre o TabbedPane com texto vertical, Veja se você suites fins.
Eu tive um jogo com este, que não estava funcionando muito bem, inicialmente, porque os limites de etiqueta eram componentes exatamente quadrados e causados ??à direita do rótulo de mudar e tornar-se obscurecida. Mas então eu percebi que era porque eu estou usando JGoodies FormLayout. Se você usar este gerenciador de layout, certifique-se de definir o tamanho da coluna para "default" "preferido" não. HTH.
Eu acho que é fora porque você está traduzindo sobre o ponto errado.
o tamanho do objeto depende do que recipiente você tem isso em, por isso, enquanto seu tamanho preferido pode ser o que quiser, o seu tamanho real não é?
Se você tem este rótulo no centro de um BorderLayout, o tamanho é sempre o tamanho total do recipiente (menos norte + altura sul, menos largura + leste-oeste)
de modo que você não tem que traduzir sobre o tamanho real, não o tamanho preferido?