Java 旋转秋千

Java 旋转秋千,java,swing,jlabel,Java,Swing,Jlabel,我目前正在尝试实现一个Swing组件,它继承自JLabel,它应该只是表示一个可以垂直定向的标签 首先: public class RotatedLabel extends JLabel { public enum Direction { HORIZONTAL, VERTICAL_UP, VERTICAL_DOWN } private Direction direction; 我认为从getPreferredSize()更改结

我目前正在尝试实现一个Swing组件,它继承自
JLabel
,它应该只是表示一个可以垂直定向的标签

首先:

public class RotatedLabel extends JLabel {

    public enum Direction {
        HORIZONTAL,
        VERTICAL_UP,
        VERTICAL_DOWN
    }

private Direction direction;
我认为从
getPreferredSize()
更改结果是个好主意:

然后,在我将绘画卸载到原始的
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);
}
它似乎在某种程度上起作用,因为文本现在是垂直显示的。但是,位置和大小已关闭

实际上,背景的宽度(本例中为橙色)与周围
JFrame
的高度相同,这是。。。不是我想的那样


有没有办法用合适的方式解决这个问题?甚至鼓励将渲染委托给超类吗?

我认为它是关闭的,因为您在翻译错误的点

对象的大小取决于它所在的容器,因此,虽然您首选的大小可能是您想要的大小,但实际大小却不是

如果此标签位于BorderLayout的中心,则大小始终为容器的完整大小(减去北+南高度,减去东+西宽度)


所以你不需要翻译实际尺寸,而不是首选尺寸吗?

我现在在同事的帮助下完成了这项工作。基本上,我现在有一个字段指示是否交换高度/宽度,该字段仅在原始
JLabel
进行绘制时处于活动状态

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;
}

我不知道现在是否相关, 但是在搜索同样的东西时,我在网上发现了一个非常好的实现,

检查一下,它是一个在带有垂直文本的选项卡窗格上的实现,
看看它是否适合您的用途。

我已经玩过这个游戏,它最初运行得不太好,因为标签边界是完全方形的,导致标签右侧的组件移动并变得模糊。但我后来意识到这是因为我使用的是JGoodies FormLayout。如果使用此布局管理器,请确保将列大小设置为“首选”而不是“默认”。嗯。

嗯。。。不相当地由于标签的垂直(现在为水平)对齐居中,因此放置有点偏离,但大小现在正好是正方形。可能是超类不关心我重写的getPreferredSize方法,因此不根据我的边界绘制自己吗?您能提供完整的类吗?请参阅–提到的许可证是一个非常自由的类,以BSD为模型(尽管许可证文本到目前为止只有德语版本)。missed“(”在
gr.translate0中,getPreferredSize().getHeight()
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;
}