java swing: Неправилни размери на завъртян JComponent след преоразмеряване

Има ли някакъв начин да се коригират размерите за завъртян компонент?

В моето приложение за люлеене бих искал да мога да завъртя единичен панел и той да реагира правилно при преоразмеряване на събития. Завъртането е право напред, но при преоразмеряване размерите на височината и ширината се обръщат. Почти би могло да работи, ако извикване на setSize беше извикано от отменено paint() повикване за размяна на размерите, но това не работи, защото setSize предизвиква друго извикване на рисуване и последва рекурсия... Имам също се опита да добави ComponentAdapter за обработка на размяната при събития за преоразмеряване, но получи същия резултат.

И така, ето опростен пример за това, с което работя. Компонентите тук са бутони, но логиката важи и за JComponent като JPanel. Бутон c се завърта с JXTransformer, но това не преоразмерява (това е коментирано в кода, но можете да добавите класа JXTransformer към classpath, ако желаете). Ако компилирате примера, опитайте да преоразмерите прозореца и вижте как се държи завъртяният бутон. Екранна снимка: (Каза, че не мога да публикувам екранни снимки, но тези връзки изглеждат активни..)

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

Ако добавя трансформация на мащаба, преоразмеряването е правилно, но компонентът е изкривен извън използваемостта. екранна снимка:

https://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());


    }
}

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