当前位置: 首页 > 知识库问答 >
问题:

Java旋转非方形JPanel组件

尹雅健
2023-03-14

由于操作系统的限制,我试图旋转填充了文本标签的网格布局,以模拟纵向视图。它们所在的JPanel不是正方形的,所以当旋转90度时,标签会根据JPanel的尺寸被截断。是否可以根据旋转调整布局的大小,使其仍然适合JPanel?对此进行的研究显示了许多旋转选项,但仅适用于方形JPanels。

为了进一步解释我的问题:当我旋转绘制在里面的标签时,它们保持格式化为正常方向的 x,y,我希望它格式化布局以适应 90 度旋转的 x,y(所以基本上 y 和 x 被翻转)。目前,我的网格的一部分在旋转后被切断。此外,最终显示应适合当前 JPnel 中填写的所有 13 x 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();
   }

}

共有1个答案

万铭
2023-03-14

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

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

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

字段面板周围的红色Line

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过滤器

更新

并使用您的< code >屏幕面板(没有自定义绘画)...

 类似资料:
  • 问题内容: 我到处搜索,但找不到答案。 如何在Java中旋转矩形? 这是我的一些代码: 我尝试了g2d.rotate(100D); 但它没有用。提前致谢。 这是我编辑的代码: 问题答案: 对于图像,必须将Graphics2D的drawImage方法与相对的AffineTransform一起使用。 对于形状,您可以旋转Graphics2D本身: 顺便说一句,您应该重写paintComponent方法

  • 问题内容: 我需要创建围绕其中心旋转的矩形(因此它们不必平行于坐标系的轴)。因此,基本上每个矩形都可以由 center-X , center-Y , width , height 和 angle定义 。然后,我要做的是对这些矩形中是否包含某些点进行计算(因此不会涉及任何绘图)。我想我不能使用该类,因为这些矩形将始终与坐标系的x和y轴平行。是通过编写自己的矩形类来获得此功能的唯一方法,还是可以使用任

  • 我正在尝试旋转并将其显示在中(位于中)。当前结果产生一个白色正方形,在黑色背景下旋转10度,但图像不在正方形内。我知道不是空的,因为本身在不旋转时会正确地显示在中。 代码如下:

  • 问题内容: 因此,目标是将阵列中的元素正确旋转一次。举个例子; 如果, 则将成为 这是我所拥有的: 但是,这无法说明何时大于数组的长度。我读到我应该将更大的存储在另一个Array中,但是看到变量是不确定的,因此我不确定这是最好的解决方案。提前致谢。 问题答案: 在代码中添加一个模数组长度: 您还应该创建一个要复制到的新值,以免覆盖以后需要的值。

  • 我写了一个方法,随机生成多边形形状,然后在屏幕上旋转和移动。因为我想检测与这些形状的碰撞,所以我没有使用Graphics2D旋转它们,而是使用仿射变换来旋转它们。但由于某些原因,某些形状被旋转弄得一团糟,而其他形状则不受影响。下面是一个导致问题的形状示例。 如果用以下直线替换这些点,则形状基本保持不变。下面的形状当然是对称的,但是旋转方法确实适用于其他随机生成的不均匀形状。

  • 问题内容: 我已经在中绘制了一些图形,例如圆形,矩形等。 但是我想绘制一些旋转了特定程度的图形,例如旋转的椭圆。我该怎么办? 问题答案: 如果您使用plain ,则强制转换为first: 旋转整个: 要重置旋转(因此您只旋转一件事): 例: