java swing:调整大小后旋转的JComponent上的尺寸不正确

时间:2012-08-06 23:29:30

标签: java swing resize rotation paintcomponent

有没有办法纠正旋转组件的尺寸?

在我的swing应用程序中,我希望能够旋转单个面板,并使其正确响应以调整事件大小。旋转是直接的,但在调整大小时,高度和宽度尺寸相反。如果从重写的paint()调用调用setSize调用以交换维度,它几乎可以工作,但这不起作用,因为setSize导致另一个调用绘制发生,然后递归...我已经...还试图添加一个ComponentAdapter来处理resize事件的交换,但得到了相同的结果。

所以,这是我正在使用的简化示例。这里的组件是按钮,但逻辑也适用于像JPanel这样的JComponent。按钮c随JXTransformer一起旋转,但这不会调整大小(它在代码中被注释掉了,但如果你愿意,可以将JXTransformer类添加到类路径中)。如果编译示例,请尝试调整窗口大小并查看旋转按钮的行为方式。截图: (它说我无法发布截图,但这些链接似乎是实时的..)

http://i.stack.imgur.com/S3qmb.png

如果我添加了比例变换,则调整大小是正确的,但是组件的失真超出了可用性。截图:

http://i.stack.imgur.com/K4l9e.png

我在这里看到很多关于旋转部分的问题,但没有关于调整大小的问题。例如,A rotated square panel in Java GUI

谢谢!

代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class RotatingTest {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new BorderLayout());

        // The button rotates, but the height/width dimensions are incorrect
        RotatedButton a = new RotatedButton("ROTATED CONTENTS!");

        JButton b = new JButton("Normal Contents");

        JButton c = new JButton("Transformer Contents");
//      JXTransformer t = new JXTransformer(c);
//      t.rotate(Math.toRadians(90));

        panel.add(a, BorderLayout.CENTER);
        panel.add(b, BorderLayout.WEST);
//      panel.add(t, BorderLayout.EAST);

        panel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);

    }
}
class RotatedButton extends JButton{

    private static final long serialVersionUID = -3355833063753337573L;

    RotatedButton(String string){
        super(string);
    }


    @Override
    protected void paintComponent(Graphics g) {

        int width = getWidth();
        int height = getHeight();

        Graphics2D graphics = (Graphics2D) g;
        AffineTransform txOrig = graphics.getTransform();
        AffineTransform transformer = new AffineTransform(txOrig);

        transformer.translate(width/2, height/2);
        transformer.rotate(Math.toRadians(90));
        transformer.translate(-height/2, -width/2);

        // this scaling fits the button to the window, but distorts the contents
//      double coef1 = (double)width / (double)height;
//      double coef2 = (double)height / (double)width;
//      transformer.scale(coef2, coef1);

        // this line sets the rotation, comment out to disable
        graphics.setTransform(transformer);

        super.paintComponent(graphics);
        graphics.setTransform(txOrig);
        graphics.dispose();

        System.out.println("Parent size: "+getRootPane().getParent().getSize());
        System.out.println("this size: "+getSize());


    }
}

1 个答案:

答案 0 :(得分:0)

所以,这里的问题是JComponents在设置它们的大小时并不关心它们实际上是什么。在paintComponent()中修改某些内容时,它只会影响组件的表面部分,而不会影响组件实际返回的任何内容。你想要做的是改造你的paintComponent()方法,或者改变你调整组件大小的方式。

想象一下,当您将图像放在太大的按钮上时。按钮将只显示它可以显示的内容,其余与按钮无关。在JComponent上旋转图形的方式完全相同。您可以提前创建图形,并将大小设置为(这是复杂的方式),或者如果您只旋转90度,只需更改为setSize()放置的int。我总是发现第二个非常简单,因为你可以不加额外的代码不断改变它的大小,你只需要记住切换所有的尺寸。

但是,如果您希望将其放置在不是90度的倍数的角度,则必须为该组件制作一个更大的正方形。(使用毕达哥拉斯理论)这可能看起来很愚蠢,但是从左上角开始考虑如何制作所有坐标。该角定义了该对象的位置,但如果它不是绝对的(最高的最左边的点),那么使用该组件的任何东西都必须手动查看组件的每个部分而不是仅仅计算它。

希望这会有所帮助,但可能会很晚。