java swing: неправильные размеры повернутого компонента JComponent после изменения размера

Есть ли способ исправить размеры повернутого компонента?

В моем приложении Swing я хотел бы иметь возможность вращать отдельную панель, чтобы она правильно реагировала на события изменения размера. Вращение выполняется просто, но при изменении размера размеры высоты и ширины меняются местами. Это могло бы почти сработать, если бы вызов setSize был вызван из переопределенного вызова paint (), чтобы поменять местами размеры, но это не сработает, потому что setSize вызывает другой вызов рисования, и последует рекурсия ... Я также попытался добавить ComponentAdapter для обработки смены мест при изменении размера, но получил тот же результат.

Итак, вот упрощенный пример того, с чем я работаю. Компонентами здесь являются кнопки, но логика применима и к JComponent, так же как и к JPanel. Кнопка c вращается с помощью JXTransformer, но при этом не изменяется размер (это закомментировано в коде, но вы можете добавить класс JXTransformer в путь к классам, если хотите). Если вы компилируете образец, попробуйте изменить размер окна и посмотрите, как ведет себя повернутая кнопка. Скриншот: (В нем сказано, что я не могу публиковать скриншоты, но эти ссылки кажутся живыми ..)

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

Если я добавлю масштабное преобразование, изменение размера будет правильным, но компонент будет искажен за пределами удобства использования. Снимок экрана:

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

Я видел здесь много вопросов, касающихся вращающейся части, но ничего не касалось проблемы изменения размера. Например, повернутая квадратная панель в графическом интерфейсе Java

Спасибо!

Код:

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());


    }
}

person aacisuan    schedule 06.08.2012    source источник
comment
Я бы сэкономил вам деньги и использовал JXLayer (java.net/projects/jxlayer ), если вы не используете Java 7 или JLayer (docs.oracle.com/javase/7/docs/api/javax/swing/JLayer.html), если вы (учебник JLayer docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html)   -  person MadProgrammer    schedule 07.08.2012


Ответы (1)


Итак, проблема здесь в том, что JComponents не заботится о том, что на самом деле на них, при установке их размера. Когда вы что-то изменяете в paintComponent(), это влияет только на поверхностные части компонента, а не на все, что фактически будет возвращено из компонента. Что вам нужно сделать, так это переделать свой paintComponent() метод или изменить способ изменения размера компонента.

Думайте об этом, как если бы вы помещали изображение на слишком большую кнопку. Кнопка просто отображает то, что может, а остальное не имеет значения для кнопки. Поворот графики на JComponent выполняется точно так же. Вы можете заранее создать графику и установить для этого свой размер (это сложный способ), или, если вы поворачиваете только на 90 градусов, просто измените значение int для setSize(). Я всегда считал второй очень простым, так как вы можете постоянно изменять его размер без дополнительного кода, вам просто нужно не забыть переключать все свои измерения.

Если, однако, вы хотите расположить его под углом, не кратным 90 градусам, вам придется сделать квадрат большего размера, чтобы компонент мог сесть в него. (Используя теорию Пифагора). Это может показаться глупым, но подумайте об этом. как делаются все координаты, из левого верхнего угла. этот угол определяет местоположение этого объекта, но если он не является абсолютным (самая верхняя левая точка), тогда все, что работает с этим компонентом, должно будет вручную просматривать каждую часть компонента, а не просто вычислять ее.

Надеюсь, это поможет, хоть и поздно.

person Harper    schedule 09.10.2013