2

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

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

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

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

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

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

我在这里看到了很多讨论旋转部分的问题,但没有关于调整大小的问题。例如,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());


    }
}
4

1 回答 1

0

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

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

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

希望这会有所帮助,尽管可能已经晚了。

于 2013-10-09T18:12:35.213 回答