gpt4 book ai didi

Java旋转非方形JPanel组件

转载 作者:行者123 更新时间:2023-11-30 09:04:23 24 4
gpt4 key购买 nike

由于操作系统限制,我正在尝试旋转填充有文本标签的 GridLayout 以模拟纵向 View 。它们所在的 JPanel 不是方形的,因此当旋转 90 度时,标签会根据 JPanel 的尺寸被切断。是否可以根据旋转调整布局大小以仍然适合 JPanel?对此的研究表明有很多旋转选项,但仅适用于方形 JPanel。

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

编辑:使用模糊的注释表明我需要在旋转后绘画,但这样做会裁剪网格并且不会填充回我喜欢的大小。

J面板代码:

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

}

最佳答案

旋转组件的过程比仅仅绘制旋转图像要复杂得多。有许多相互关联的层会产生契约(Contract)义务。

例如,设置为传递给组件进行绘制的Graphics上下文的裁剪矩形的大小由组件的当前大小决定,这个大小由布局管理器计算,但可能会考虑单个组件的首选大小...

需要考虑很多重新布线……说我懒,但如果我能找到现成的解决方案,我更愿意使用它,所以基于 this example ,我可以生成以下...

Rotate

字段面板周围的红色 LineBorder 显示整个组件都已旋转,而不仅仅是它的子组件。 pack 的使用也表明该解决方案仍在履行其对其余 API 的契约(Contract)义务

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

已更新

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

Rotate

关于Java旋转非方形JPanel组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25252127/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com