简体   繁体   English

setLayout(null)时,JPanel上的组件未显示

[英]Component on JPanel not showing when setLayout(null)

Someone can tell why the combobox is not showing ? 有人可以告诉我为什么组合框不显示吗? I have a Controller: 我有一个控制器:

public class TestController extends JPanel {

TestView cgView;

public TestController() 
{

    setLayout(null);

    cgView=new TestView();

    add(cgView);

}
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
             JFrame fr = new JFrame("testt");
                fr.setSize(1200,1000);
                fr.setResizable(false);

                TestController cgc=new TestController();
                fr.setBackground(Color.white);
                fr.setVisible(true);

                fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                fr.add(cgc);

         }
        });
    }


}

And a view 和一个观点

public class TestView extends JPanel{
    private static final long serialVersionUID = 1L;

    public JComboBox<String> comboBox; 

    public TestView() {

          comboBox= new JComboBox<>(new String[] {"option1", "option2" });
          comboBox.setBounds(100,500, 100, 20);
          add(comboBox);

    }
}

Because of setLayout(null) in TestController, I can't see the comboBox. 由于TestController中的setLayout(null) ,我看不到comboBox。 If I add add(cgView.comboBox) to my TestContoller(), so that it looks like this: 如果我将add(cgView.comboBox)添加到TestContoller()中,则它看起来像这样:

public TestController() 
    {

        setLayout(null);

        cgView=new TestView();

        add(cgView);
        add(cgView.comboBox);

    }

Than I can see it. 比我能看到的。 Can someone tell why? 有人可以告诉为什么吗?

So my solution is to always add the components in TestController, or to pass TestController as an atribute to TestView (so in TestView() I would add them like this this.parentPanel.add(comboBox). Is there any other solution? 因此,我的解决方案是始终将组件添加到TestController中,或者通过TestController作为TestView的一个属性(因此在TestView()中,我将这样添加它们:this.parentPanel.add(comboBox)。还有其他解决方案吗?

  • Don't use null layout, almost ever 几乎不使用空布局
  • Instead use the best combination of layouts nested in JPanels to achieve a pleasing layout for your GUI. 而是使用嵌套在JPanels中的布局的最佳组合来为您的GUI实现令人愉悦的布局。
  • If you do use null layout then you are fully responsible for setting the size and location of all components added to that container. 如果您确实使用null布局,那么您将完全负责设置添加到该容器的所有组件的大小和位置。
  • Your current problem is that you never give TestView a size or location and have then added it to a null layout-using container. 您当前的问题是,您永远不会给TestView一个尺寸或位置,而是将其添加到使用空布局的容器中。
  • You shouldn't add a component (above, your JComboBox) to more than one container. 您不应将一个组件(上面的JComboBox)添加到多个容器中。
  • Don't call setVisible(true) on the JFrame until after you've added all components and called pack() on it. 在添加所有组件并在其上调用pack() 之后 ,才对JFrame调用setVisible(true)

eg, 例如,

import java.awt.*;
import javax.swing.*;

public class TestController extends JPanel {
   private static final int PREF_W = 1000;
   private static final int PREF_H = 800;
   TestView cgView;

   public TestController() {
      setLayout(null);
      cgView = new TestView();
      cgView.setSize(getPreferredSize());
      add(cgView);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            JFrame fr = new JFrame("testt");
            // fr.setSize(1200, 1000);
            fr.setResizable(false);
            TestController cgc = new TestController();
            fr.setBackground(Color.white);
            // fr.setVisible(true);
            fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fr.add(cgc);
            fr.pack(); //!! added 
            fr.setVisible(true); // !! moved
         }
      });
   }
}

But better off using layouts: 但是最好使用布局:

import java.awt.*;
import javax.swing.*;

public class TestController extends JPanel {
   private static final int PREF_W = 1000;
   private static final int PREF_H = 800;
   TestView cgView;

   public TestController() {
      //!!  setLayout(null);
      cgView = new TestView();
      //!! cgView.setSize(getPreferredSize());
      add(cgView);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            JFrame fr = new JFrame("testt");
            // fr.setSize(1200, 1000);
            fr.setResizable(false);
            TestController cgc = new TestController();
            fr.setBackground(Color.white);
            // fr.setVisible(true);
            fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            fr.add(cgc);
            fr.pack(); //!! added 
            fr.setVisible(true); // !! moved
         }
      });
   }
}

class TestView extends JPanel {
   private static final long serialVersionUID = 1L;
   public JComboBox<String> comboBox;

   public TestView() {
      comboBox = new JComboBox<String>(new String[] { "option1", "option2" });
      // comboBox.setBounds(100, 500, 100, 20);
      add(comboBox);
   }
}

Edit 编辑
The OP asked in a comment: OP在评论中要求:

'Almost never'? '几乎从不'? In which cases you would use it [the null layout]? 在哪种情况下,您会使用[null布局]?

I use it rarely, such as when I want to move components around via animation or with a MouseListener, but even then, many suggest that you create your own layout to handle that such as Rob Camick's Drag Layout 我很少使用它,例如当我想通过动画或使用MouseListener来移动组件时,但是即使如此,许多人还是建议您创建自己的布局来处理它,例如Rob Camick的Drag Layout。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM