本文介绍了Java的旋转非方形JPanel组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图充满文本标签来模拟纵向视图GridLayout的旋转,由于操作系统的限制。在JPanel他们里面不是方形,所以旋转90度时,标签基础上,JPanel的尺寸切断。是否有可能调整的基础上的旋转在JPanel内仍然适合的布局?研究到这个表现出对旋转许多选择,但仅限于方形JPanels。

要进一步说明我的问题:当我旋转涂标签,里面却留格式化正常的面向X,Y,我想它格式化布局,以适应90度旋转的x,y(所以基本上y和X的翻转)。目前我的网格的部分被旋转后切断。也最终显示应适用于所有13所24个字母填在当前JPnel。

编辑:使用含糊的评论表明我需要旋转后作画,但这样做裁剪网格,不填回我的preferred尺寸

的JPanel code:

 进口java.awt.Color中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.GridLayout中;
进口javax.swing.JLabel中;
进口javax.swing.JPanel中;公共类屏幕继承JPanel {   私人的JLabel [] [] =标签JLabel的新[13] [24];
   私人GridLayout的布局;   公众网(){      //的setLocation(315,35);
      布局=新的网格布局(13,24);
      。布局preferredLayoutSize(本);
      //的setBounds(315,65,243,350);
      的setBounds(315,65,243,350);
      的setLayout(布局);      对(INT I = 0; I&; 13;我++){
         对于(INT J = 0; J< 24; J ++){
            标签[I] [J] =新的JLabel();
            标签由[i] [j]的.setBackground(Color.BLACK);
            添加(标签[I] [J]);
         }
      }      //测试新的信
      对(INT I = 0; I&; 13;我++){
         对于(INT J = 0; J< 24; J ++){
            标签由[i] [j]的.setText(T);
            标签由[i] [j]的.setForeground(Color.GREEN);
         }
      }      的setBackground(Color.black);
      调用setVisible(真);
      重绘();
   }   @覆盖
   公共无效的paintComponent(图形G){
      //用于旋转屏幕图形到正确的方向
      Graphics2D的G2D =(Graphics2D的)克;
      INT W2 =的getWidth()/ 2;
      INT H2 =的getHeight()/ 2;
      g2d.rotate(Math.PI / 2,W2,H2);      super.paintComponent方法(G);
      的setSize(243350);   }
}

测试code:

 进口javax.swing.JFrame中;
进口javax.swing.JLayeredPane中;公共类RotateTest {   公共静态类框架延伸的JFrame {      公共帧(){
         屏幕屏幕=新画面();         JLayeredPane的窗格=新的JLayeredPane();
         setUndecorated(假);
         的setSize(800,480);         调用setVisible(真);
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         pane.add(屏幕,0,0);
         pane.setVisible(真);
         加(面板);
      }
   }   公共静态无效的主要(字串[] args){
      帧一帧=新帧();
   }}


解决方案

旋转组件的过程是比较复杂的则只是画旋转图像。有许多能产生合同义务互联层的

例如,设置为传递到你的组件绘画由组件的电流大小决定的图形上下文中的剪贴矩形的尺寸,这个尺寸由布局管理器计算的,但也可以考虑各个部件的preferred大小...

这是一个很大重新布线的需要考虑......叫我懒,但如果我能找到一个现成的解决方案,我想preFER使用它,因此基于this例如,我可以生成以下...

红色 LineBorder 绕场面板是否有表明整个组件被旋转,而不仅仅是它的孩子。使用也证明了这个解决方案仍然是尊重它的合同义务的API的其余部分。

 进口java.awt.BorderLayout中;
进口java.awt.Color中;
进口java.awt.EventQueue中;
进口java.awt.GridBagLayout中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口javax.swing.JButton中;
进口javax.swing.JComponent中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.JTextField中;
进口javax.swing.SwingUtilities中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;
进口javax.swing.border.LineBorder中;
进口org.jdesktop.jxlayer.JXLayer;
进口org.pbjar.jxlayer.demo.TransformUtils;
进口org.pbjar.jxlayer.plaf.ext.transform.DefaultTransformModel;公共类RotateExample {    公共静态无效的主要(字串[] args){
        新RotateExample();
    }    公共RotateExample(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                }                JFrame的帧=新的JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的BorderLayout());
                frame.add(新ExamplePane());
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类ExamplePane继承JPanel {        私人FieldPane fieldPane;
        私人DefaultTransformModel transformModel;        私人JButton的旋转;
        私人双角;        公共ExamplePane(){            的setLayout(新的BorderLayout());            旋转=的新的JButton(旋转);
            rotate.addActionListener(新的ActionListener(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    transformModel.setRotation(Math.toRadians((角+ = 90)));
                    SwingUtilities.getWindowAncestor(ExamplePane.this).pack();
                }
            });
            fieldPane =新FieldPane();            transformModel =新DefaultTransformModel();
            transformModel.setRotation(Math.toRadians(0));
            transformModel.setScaleTo preferredSize(真);
            JXLayer<&的JComponent GT; rotatePane = TransformUtils.createTransformJXLayer(fieldPane,transformModel);            内容的JPanel =新JPanel(新的GridBagLayout());
            content.add(rotatePane);            加(旋转,BorderLayout.SOUTH);
            加(内容);        }
    }    公共类FieldPane继承JPanel {        公共FieldPane(){
            setBorder(新LineBorder(Color.RED));
            的setLayout(新的GridBagLayout());            JTextField的领域=新的JTextField(10);
            field.setText(世界,你好);            加(场);        }
    }
}

注意事项

这需要(我用的是第3版)的(我用的是1.6.4版本)和皮特勃洛克的很好的例子,它似乎不再可用在网络上...

我已经把JXLayer(第3版)和皮特的例子的所有源$ C ​​$ C到一个单一的,我会建议,如果你有兴趣,你抢副本,并将其存储一些地方是安全的。

您还需要

更新

和使用屏幕面板(不风俗画)...

I am attempting to rotate a GridLayout filled with text labels to simulate a portrait orientation view due to an OS restriction. The JPanel they are inside of is not square, so when rotating 90 degrees the labels cut off based on dimensions of the JPanel. Is it possible to resize the layout based on the rotation to still fit within the JPanel? Researching into this showed many options for rotations, but only for square JPanels.

To further explain my problem: when I rotate the labels painted inside they stay formatted to the normal oriented x,y, and I want it to format the layout to fit into the 90 degree rotated x,y (so basically y and x are flipped). currently a portion of my grid is cut off after rotating. Also the final display should fit all 13 by 24 letters filled in the current JPnel.

edit: Using vague comments shows I need to paint after rotating, but doing so crops the grid and does not fill back to my preferred size.

JPanel code:

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

   }
}

test code:

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

}
解决方案

The process of rotating a component is more complicated then just painting the rotated image. There are a number of interconnected layers which generate contractual obligations.

For example, the size of the clipping rectangle set to the Graphics context that is passed to your component for painting is determined by the current size of the component, this size is calculated by the layout manager, but may consider the preferred size of the individual component...

That's a lot of re-wiring that needs to be considered...call my lazy, but if I can find a ready made solution, I'd prefer to use it, so based on this example, I can generate the following...

The red LineBorder around the field panel is there to show that the entire component is been rotated, not just it's children. The use of pack also demonstrates that this solution is still honouring it's contractual obligations to the rest of the 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);

        }
    }
}

Caveats

This requires JXLayer (I was using version 3), SwingX (I was using version 1.6.4) and Piet Blok's excellent examples, which no longer seem to be available on the net...

I've put all the source code of JXLayer (version 3) and Piet's examples into a single zip and I would suggest, if you are interested, you grab a copy and store it some where safe.

You will also need JHLabs filters

Updated

And using your Screen panel (without the custom painting)...

这篇关于Java的旋转非方形JPanel组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 12:12