setVisible问题(true)

时间:2010-03-09 01:55:28

标签: java visibility gridbaglayout

下面显示的两个例子是相同的。两者都应该产生相同的结果,例如生成JPanel上显示的图像坐标。 示例1完美地工作(打印图像的坐标),但是示例2为坐标返回0。

我想知道为什么因为,在两个例子中,我在添加面板后放置了setvisible(true)。唯一的区别是示例1使用extends JPanel和示例2 extends JFrame

示例1:

    public class Grid extends JPanel{
       public static void main(String[] args){
          JFrame jf=new JFrame();
          jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
          final Grid grid = new Grid();
          jf.add(grid);
          jf.pack();

          Component[] components = grid.getComponents();        
          for (Component component : components) {
           System.out.println("Coordinate: "+ component.getBounds());       
          }   

          jf.setVisible(true);        
        }
    }

示例2:

public class Grid extends JFrame {

  public Grid () {
    setLayout(new GridBagLayout());
    GridBagLayout m = new GridBagLayout();
    Container c = getContentPane();
    c.setLayout (m);
    GridBagConstraints con = new GridBagConstraints();

    //construct the JPanel
    pDraw = new JPanel();
    ...
    m.setConstraints(pDraw, con);
    pDraw.add (new GetCoordinate ()); // call new class to generate the coordinate
    c.add(pDraw);

    pack();
    setVisible(true);
    }

    public static void main(String[] args) {
       new Grid();
    }
   }

3 个答案:

答案 0 :(得分:2)

问题在于,在第二个示例中,您尝试在将组件添加到其容器之前(通过调用add())并在框架的内容布局之前打印出组件的边界(通过致电pack())。

这是我尝试重现示例1. ...

这是我尝试重现示例2.我添加了SwingUtilities调用以将内容置于正确的线程中,并在评论的帮助下填写了GetCoordiates构造函数的内容:< / p>

class GetCoordinate extends JLabel {
    public GetCoordinate() {
        setText("Foo!");
        System.out.println("Coordinate: " + this.getBounds());
    }
}

public class Grid extends JFrame {
    public Grid() {
        setLayout(new GridBagLayout());
        GridBagLayout m = new GridBagLayout();
        Container c = getContentPane();
        c.setLayout(m);
        GridBagConstraints con = new GridBagConstraints();

        // construct the JPanel
        final JPanel pDraw = new JPanel();
        m.setConstraints(pDraw, con);
        pDraw.add(new GetCoordinate()); // call new class to generate the
                                        // coordinate
        c.add(pDraw);

        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Grid();
            }
        });
    }
}

正如您所描述的那样,它打印出的大小为零:

  

坐标:java.awt.Rectangle [x = 0,y = 0,width = 0,height = 0]

但是,如果在添加组件并打包框架后打印出尺寸,则应该可以使用。以下是我的示例2的修改版本,其中我添加了一个方法GetCoordinate.printBounds()并调用该方法,所有内容都已添加并布局:

class GetCoordinate extends JLabel {
    public GetCoordinate() {
        setText("Foo!");
        // Let's not try to do this here anymore...
//        System.out.println("Coordinate: " + this.getBounds());
    }

    public void printBounds() // <-- Added this method
    {
        System.out.println("Coordinate: " + this.getBounds());
    }
}

public class Grid extends JFrame {
    public Grid() {
        setLayout(new GridBagLayout());
        GridBagLayout m = new GridBagLayout();
        Container c = getContentPane();
        c.setLayout(m);
        GridBagConstraints con = new GridBagConstraints();

        // construct the JPanel
        final JPanel pDraw = new JPanel();
        m.setConstraints(pDraw, con);
        final GetCoordinate content = new GetCoordinate();
        pDraw.add(content);
        c.add(pDraw);

        pack();
        setVisible(true);
        content.printBounds();  // <-- Added this
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Grid();
            }
        });
    }
}

通过这些更改,我得到以下控制台输出,包括我的内容的非零大小:

  

坐标:java.awt.Rectangle [x = 5,y = 5,width = 23,height = 16]

答案 1 :(得分:0)

此类异常的常见原因是未能在EDT开始。在这种情况下,我无法从您的代码中看出有什么不同:特别是,不清楚第二个示例的打印位置。

答案 2 :(得分:0)

contoh

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author LENOVO G40
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new FrmMenuUTama().setVisible(true);
    }
}