1

上半分に回転する四角形があり、下半分に四角形を停止/実行して回転させることができるボタンがある小さなスイングアプリケーションを開発しました。を使用しGridLayoutて、回転する正方形とボタンを配置しました。(別の方法として、2 つJPanelの s を使用することもできます。1 つは回転する正方形で、2 番目にはボタンが含まれます。このボタンを使用すると、適切なサイズで表示されます。)

ここにコードがあります:-

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

FlowLayoutPreferredSize子からのみ受け入れJComponents、親と継続的にサイズ変更できません

GridLayout(あなたの問題)PreferredSize最も大きくて広いものから取り出し、コンテナ内の残りの部分にJComponents同じものを設定するには、サイズ変更可能で、親と継続的に使用しますDimmensionJComponentsJComponents

pre_implemented LayoutManagerfor JFrame、 useを使用する必要がありBorderlayoutJComponentsサイズ変更可能で、親と継続的に使用できます (CENTER エリアのみ、座標の 1 つだけで残ります)。

削除する

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

他の人が言ったように (+1 mKorbel と HFOE)

  • 問題は、可視に設定する前に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 に答える