1

我开发了一个小型摆动应用程序,其中上半部分有一个正方形旋转,下半部分有一个按钮可以停止/运行正方形旋转。我用GridLayout来放置旋转方块和按钮。(另一种选择是使用 2 JPanels,一个是旋转正方形,第二个包含按钮。使用此按钮会显示适当的大小。)

这是代码:-

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;


public class Rotation {
JButton jbtn=new JButton("Stop");
component jpn2=new component();    //created a JPanel named jpn2 and got a reference to its timer object.
Timer timer=jpn2.timer;
Rotation()
{


    JFrame jfrm=new JFrame("Rotating a square about a center");
    jfrm.setSize(400,400);
    jfrm.setLayout(new GridLayout(2,1));
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //JPanel jpnl=new JPanel();

    //jpnl.add(jbtn);

    jbtn.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){
        if(e.getActionCommand().equals("Stop"))
        {
            timer.stop();
            jbtn.setText("Spin");
        }
        if(e.getActionCommand().equals("Spin"))
        {
            timer.start();
            jbtn.setText("Stop");
        }

    }});

    jfrm.add(jpn2);
    jfrm.add(jbtn);

    //jfrm.add(new JButton("Click"));
    jfrm.setVisible(true);
    //jfrm.setOpacity(0.8f);
}
public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException
{
    //JFrame.setDefaultLookAndFeelDecorated(true);
    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    SwingUtilities.invokeLater(new Runnable(){public void run(){new Rotation();}});
}

}

class component extends JPanel implements ActionListener
{
Timer timer;
int theta=0;
component()
{
    timer=new Timer(10,this);
    timer.start();
}
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Graphics2D g2=(Graphics2D)g;
    g2.rotate(theta,100,100);
    g2.fillRect(50, 50, 100,100);
}
public void actionPerformed(ActionEvent e)
{
    //Changing a global variable and then drawing the rectangle again and hence indirectly the square rotates.
    theta=theta+10;
    if(theta==360)
        theta=0;
    repaint();
}
}

这是输出: -

输出

但我的困惑是当我决定使用FlowLayout而不是GridLayout我只得到按钮而不是旋转方块时。据我所知,FlowLayout将组件放在一行中,如果空间小于它使用多行。谁能解决我目前无法解决的这个愚蠢的小问题。

4

3 回答 3

3

您的问题是您使用setSize(...)这些布局将完全按照您的要求进行 - 将 GUI 的大小设置为该大小,无论是否所有内容都没有显示。一般来说,您希望避免调用setSize(...),而是getPreferredSize()在必要时覆盖组件并在显示它之前打包您的 GUI,让组件自行调整大小。请注意,FlowLayout 有其用途,但与其他布局相比,它不是一堆中“最聪明”的布局(在我看来)。

于 2012-10-25T13:54:29.773 回答
3

FlowLayout只接受PreferredSize来自它JComponents的孩子,不能随着它的父母不断调整大小

GridLayout(您的问题)PreferredSize从更大更宽的容器中获取并为容器中的其余部分JComponents设置相同的大小,并与它的父级连续DimmensionJComponentsJComponents

必须使用 pre_implemented LayoutManagerfor JFrame, use Borderlayout,JComponents可调整大小并与其父级连续(仅限 CENTER 区域,仅与坐标之一休息)

消除

jfrm.setLayout(new GridLayout(2,1));

并改变

jfrm.add(jpn2); 
jfrm.add(jbtn, BorderLayout.SOUTH);

通知JFrame

frm.add(jpn2); equals frm.add(jpn2, BorderLayout.CENTER);
于 2012-10-25T14:00:32.620 回答
2

正如其他人所说(mKorbel 和 HFOE +1)

  • 问题是您在设置为可见之前使用setSize(..)宁可调用。pack()JFrame

  • 您还必须getPrefferedSize(..)JPanel类中覆盖,这将返回您的正方形大小乘以 2(否则当它旋转时它不适合)。

  • 顺便说一句,不要把任何main(..)事情都抛在脑后。

请参阅下面的代码(使用FlowLayout但也适用于GridLayout):

使用new FlowLayout()

在此处输入图像描述

使用new GridLayout(2,1)

在此处输入图像描述

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Rotation {

    JButton jbtn = new JButton("Stop");
    component jpn2 = new component();    //created a JPanel named jpn2 and got a reference to its timer object.
    Timer timer = jpn2.timer;

    Rotation() {


        JFrame jfrm = new JFrame("Rotating a square about a center");

        // jfrm.setLayout(new FlowLayout());
        jfrm.setLayout(new GridLayout(2, 1));

        jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jbtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("Stop")) {
                    timer.stop();
                    jbtn.setText("Spin");
                }
                if (e.getActionCommand().equals("Spin")) {
                    timer.start();
                    jbtn.setText("Stop");
                }

            }
        });

        jfrm.add(jpn2);
        jfrm.add(jbtn);

        jfrm.pack();
        jfrm.setVisible(true);
    }

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {

            ex.printStackTrace();
        }

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Rotation();
            }
        });
    }
}

class component extends JPanel implements ActionListener {

    Timer timer;
    int theta = 0;
    int width = 100, height = 100;

    component() {
        timer = new Timer(10, this);
        timer.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.rotate(theta, 100, 100);
        g2.fillRect(50, 50, width, height);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(width * 2, height * 2);//multiply by 2 to fit while rotating
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //Changing a global variable and then drawing the rectangle again and hence indirectly the square rotates.
        theta = theta + 10;
        if (theta == 360) {
            theta = 0;
        }
        repaint();
    }
}
于 2012-10-25T15:18:33.037 回答