Componente JPanel no cuadrado rotativo de Java

Estoy intentando rotar un GridLayout lleno de tags de texto para simular una vista de orientación vertical debido a una restricción del sistema operativo. El JPanel en el que están dentro no es cuadrado, por lo que cuando se giran 90 grados, las tags se cortan en función de las dimensiones del JPanel. ¿Es posible cambiar el tamaño del diseño en función de la rotación para que encaje en el JPanel? Investigar esto mostró muchas opciones para rotaciones, pero solo para JPanels cuadrados.

Para explicar mejor mi problema: cuando giro las tags pintadas en su interior, permanecen formateadas en x, y, y quiero que formatee el diseño para que se ajuste a los 90 grados girados x, y (básicamente, yy son volteados) ) Actualmente, una parte de mi cuadrícula se corta después de rotar. Además, la pantalla final debe ajustarse a todas las 13 letras de 24 llenas en el JPnel actual.

editar: Usar comentarios imprecisos muestra que necesito pintar después de rotar, pero al hacerlo recorto la cuadrícula y no vuelvo a mi tamaño preferido.

Código JPanel:

import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import javax.swing.JLabel; import javax.swing.JPanel; public class Screen extends JPanel { private JLabel[][] labels = new JLabel[13][24]; private GridLayout layout; public Screen() { //setLocation(315,35); layout = new GridLayout(13, 24); layout.preferredLayoutSize(this); //setBounds(315, 65, 243, 350); setBounds(315, 65, 243, 350); setLayout(layout); for (int i = 0; i < 13; i++) { for (int j = 0; j < 24; j++) { labels[i][j] = new JLabel(); labels[i][j].setBackground(Color.BLACK); add(labels[i][j]); } } //testing new letter for (int i = 0; i < 13; i++) { for (int j = 0; j < 24; j++) { labels[i][j].setText("T"); labels[i][j].setForeground(Color.GREEN); } } setBackground(Color.black); setVisible(true); repaint(); } @Override public void paintComponent(Graphics g) { //Rotates screen graphics to correct orientation Graphics2D g2d = (Graphics2D) g; int w2 = getWidth() / 2; int h2 = getHeight() / 2; g2d.rotate(Math.PI / 2, w2, h2); super.paintComponent(g); setSize(243,350); } } 

código de prueba:

 import javax.swing.JFrame; import javax.swing.JLayeredPane; public class RotateTest { public static class Frame extends JFrame { public Frame() { Screen screen = new Screen(); JLayeredPane pane = new JLayeredPane(); setUndecorated(false); setSize(800, 480); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pane.add(screen, 0, 0); pane.setVisible(true); add(pane); } } public static void main(String[] args) { Frame frame = new Frame(); } } 

El proceso de rotación de un componente es más complicado que simplemente pintar la imagen girada. Hay una serie de capas interconectadas que generan obligaciones contractuales.

Por ejemplo, el tamaño del rectángulo de recorte establecido en el contexto de Graphics que se pasa a su componente para pintar está determinado por el tamaño actual del componente, este tamaño es calculado por el administrador de diseño, pero puede considerar el tamaño preferido del individuo componente…

Eso es una gran cantidad de cableado que debe tenerse en cuenta … llamar a mi perezoso, pero si puedo encontrar una solución preparada, preferiría usarla, por lo que basado en este ejemplo , puedo generar lo siguiente … .

Girar

El LineBorder rojo alrededor del panel de campo está ahí para mostrar que todo el componente ha sido rotado, no solo sus elementos secundarios. El uso del pack también demuestra que esta solución sigue cumpliendo sus obligaciones contractuales con el rest de la API

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.EventQueue; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.LineBorder; import org.jdesktop.jxlayer.JXLayer; import org.pbjar.jxlayer.demo.TransformUtils; import org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel; public class RotateExample { public static void main(String[] args) { new RotateExample(); } public RotateExample() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new ExamplePane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class ExamplePane extends JPanel { private FieldPane fieldPane; private DefaultTransformModel transformModel; private JButton rotate; private double angle; public ExamplePane() { setLayout(new BorderLayout()); rotate = new JButton("Rotate"); rotate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { transformModel.setRotation(Math.toRadians((angle += 90))); SwingUtilities.getWindowAncestor(ExamplePane.this).pack(); } }); fieldPane = new FieldPane(); transformModel = new DefaultTransformModel(); transformModel.setRotation(Math.toRadians(0)); transformModel.setScaleToPreferredSize(true); JXLayer rotatePane = TransformUtils.createTransformJXLayer(fieldPane, transformModel); JPanel content = new JPanel(new GridBagLayout()); content.add(rotatePane); add(rotate, BorderLayout.SOUTH); add(content); } } public class FieldPane extends JPanel { public FieldPane() { setBorder(new LineBorder(Color.RED)); setLayout(new GridBagLayout()); JTextField field = new JTextField(10); field.setText("Hello world"); add(field); } } } 

Advertencias

Esto requiere JXLayer (estaba usando la versión 3), SwingX (estaba usando la versión 1.6.4) y los excelentes ejemplos de Piet Blok, que ya no parecen estar disponibles en la red …

Puse todo el código fuente de JXLayer (versión 3) y los ejemplos de Piet en un solo archivo comprimido y sugiero que, si está interesado, tome una copia y la guarde en un lugar seguro.

También necesitarás filtros JHLabs

Actualizado

Y usando su panel de Screen (sin la pintura personalizada) …

Girar