我试图旋转填充文本标签的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上下文的剪切矩形的大小由组件的当前大小决定,此大小由布局管理器计算,但可以考虑个人的首选大小零件…
这是需要考虑的很多重新布线…叫我懒惰,但如果我能找到一个现成的解决方案,我宁愿使用它,所以基于this example,我可以生成以下…
字段面板周围的红色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<JComponent> 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的示例的所有源代码放入单个zip中,我建议,如果您有兴趣,可以抓取副本并将其存储在安全的地方.
你还需要JHLabs filters
更新
并使用您的屏幕面板(没有自定义绘画)……