Componente Java JPanel rotante non quadrato

Sto tentando di ruotare un GridLayout pieno di etichette di testo per simulare una vista di orientamento verticale a causa di una limitazione del sistema operativo. Il JPanel all’interno non è quadrato, quindi ruotando di 90 gradi le etichette vengono tagliate in base alle dimensioni dello JPanel. È ansible ridimensionare il layout basato sulla rotazione per adattarlo ancora all’interno di JPanel? La ricerca in questo ha mostrato molte opzioni per le rotazioni, ma solo per JPanel quadrati.

Per spiegare meglio il mio problema: quando ruoto le etichette dipinte all’interno rimangono formattate con la normale orientata x, ye voglio che formi il layout per adattarlo alla rotazione di x, y (quindi in pratica y e x sono invertiti ). attualmente una parte della mia griglia viene interrotta dopo la rotazione. Anche il display finale dovrebbe contenere tutti i 13 di 24 lettere riempite nell’attuale JPnel.

modifica: l’uso di commenti vaghi mostra che devo verniciare dopo aver ruotato, ma farlo ritaglia la griglia e non rientra nella mia dimensione preferita.

Codice 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); } } 

codice di prova:

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

Il processo di rotazione di un componente è più complicato quindi semplicemente dipingendo l’immagine ruotata. Vi sono numerosi livelli interconnessi che generano obblighi contrattuali.

Ad esempio, la dimensione del rettangolo di ritaglio impostato sul contesto Graphics passato al componente per la verniciatura è determinata dalla dimensione corrente del componente, questa dimensione viene calcasting dal gestore di layout, ma può considerare la dimensione preferita dell’individuo componente…

Questo è un sacco di ricablaggio che deve essere considerato … chiama il mio pigro, ma se riesco a trovare una soluzione pronta, preferirei usarlo, quindi sulla base di questo esempio , posso generare il seguente .. .

Ruotare

Il LineBorder rosso attorno al pannello del campo è lì per mostrare che l’intero componente è stato ruotato, non solo i bambini. L’uso di pack dimostra anche che questa soluzione sta ancora onorando i suoi obblighi contrattuali con il resto dell’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 actionPerformsd(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); } } } 

Avvertenze

Ciò richiede JXLayer (stavo usando la versione 3), SwingX (stavo usando la versione 1.6.4) e gli eccellenti esempi di Piet Blok, che non sembrano più disponibili sulla rete …

Ho messo tutto il codice sorgente di JXLayer (versione 3) e gli esempi di Piet in un unico zip e suggerirei, se sei interessato, di prenderne una copia e conservarla in un posto sicuro.

Avrai anche bisogno dei filtri JHLabs

aggiornato

E usando il pannello Screen (senza il dipinto personalizzato) …

Ruotare