2012-10-25 90 views
1

我开发了一个小摆动应用程序,其中有一个正方形在上半部分旋转,下半部分有一个按钮可以停止/运行正方形旋转。 我已经使用GridLayout来放置旋转的正方形和按钮。 (另一种替代方法是使用2个JPanel S,一个是带有旋转方和第二包含此按钮显示适当大小的button.Using。)流动布局工作的困惑

下面是代码: -

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

这里是输出: -

output

但我的困惑是,当我决定使用FlowLayout代替GridLayout我越来越仅按钮并没有转动平方米你是。 据我所知,FlowLayout将组件放在一行中,如果空间小于它使用多行。 任何人都可以解决这个我目前无法解决的小笨问题。

+2

请学习Java命名约定并严格遵守 – kleopatra

回答

2

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

  • 问题是你使用setSize(..)设置JFrame可见,而之前打电话pack()

  • 你也必须重写getPrefferedSize(..)JPanel类,它将返回你的平方的大小乘以2(否则当它旋转它将不适合)。

  • 在旁边注意不要在main(..)扔任何excpetion从来没有一件好事。

请参见下面的代码(使用FlowLayout也与GridLayout作品):

使用new FlowLayout()

enter image description here

使用new GridLayout(2,1)

enter image description here

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

:谢谢您的宝贵答案。 我之前没有使用过getPreferredSize()。所以我知道的是旋转方块现在使用getPreferredSize()返回它自己的大小。 可我也acheive同样的事情了setPreferredSize,像 “公共无效了setPreferredSize() \t { \t \t新的外形尺寸(宽* 2,高度×2); \t}' –

3

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

+0

:先生,我的问题是,如果我可以使用的FlowLayout(偶用的setSize)加2个按钮到JFrame,那么为什么我不能添加的JPanel和一个按钮JFrame。这样做只会添加按钮,JPanel不会被添加或显示。为什么? –

+0

@Naveen:你在上面发布的代码中使用了FlowLayout吗?发布有问题的代码总是最好的。 –

+0

:先生,在上面的代码中,我只是想用'FlowLayout()'替换'GridLayout(2,1)',而且我只获取按钮,但没有包含旋转方块的JPanel。 现在,我想要的是让他们都使用FlowLayout.If不可能,那为什么? –

3

FlowLayout只接受PreferredSize来自它童车,JComponents是不可调整大小的连续它的父

GridLayout(你的问题)采取PreferredSize大多数更大更宽JComponents并设置相同Dimmension在的JComponents休息容器,JComponents可以调整大小,不断地与它的父

必须使用pre_implemented LayoutManagerJFrame,使用BorderlayoutJComponents为Res izable,不断地与它的父

(中心区域仅与一个坐标只能休息)删除

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

,并改变

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

通知书JFrame

frm.add(jpn2); equals frm.add(jpn2, BorderLayout.CENTER); 
+0

:主席先生,我遇到的问题是,如果我可以使用FlowLayout添加2个按钮,那么为什么我不能添加一个JPanel和一个按钮(这样做只会添加按钮,不会添加或显示JPanel)。 –