Java旋转非方形JPanel组件

我试图旋转填充文本标签的GridLayout来模拟由于操作系统限制而导致的纵向视图。 它们所在的JPanel不是方形的,所以当旋转90度时,标签会根据JPanel的尺寸切断。 是否可以根据旋转调整布局大小以适应JPanel? 对此研究显示了许多旋转选项,但仅适用于方形JPanels。

为了进一步解释我的问题:当我旋转内部绘制的标签时,它们保持格式化为正常的x,y,我希望它格式化布局以适应90度旋转的x,y(所以基本上y和x都被翻转)。 目前我的网格的一部分在旋转后被切断。 此外,最终显示应适合当前JPnel中填写的所有13乘24个字母。

编辑:使用模糊的注释显示我需要在旋转后绘制,但这样做会裁剪网格并且不会填充回我喜欢的尺寸。

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

测试代码:

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

旋转组件的过程比仅绘制旋转图像更复杂。 有许多相互关联的层面产生合同义务。

例如,设置为要传递到组件进行绘制的Graphics上下文的剪切矩形的大小由组件的当前大小决定,此大小由布局管理器计算,但可以考虑个人的首选大小零件…

这是需要考虑的很多重新布线……叫我懒惰,但如果我能找到一个现成的解决方案,我宁愿使用它,所以基于这个例子 ,我可以生成以下.. 。

旋转

字段面板周围的红色LineBorder用于显示整个组件已旋转,而不仅仅是它的子项。 pack的使用也表明该解决方案仍然履行其对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); } } } 

注意事项

这需要JXLayer (我使用的是版本3), SwingX (我使用的是1.6.4版本)和Piet Blok的优秀示例,这些示例似乎不再可用于网络…

我把JXLayer(版本3)的所有源代码和Piet的例子都放在一个拉链中 ,我建议,如果你有兴趣,你可以抓一份并将它存放在安全的地方。

您还需要JHLabsfilter

更新

并使用您的Screen面板(没有自定义绘画)…

旋转