Component on JPanel not showing when setLayout(null)

人盡茶涼 提交于 2019-12-19 10:59:08

问题


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. If I add add(cgView.comboBox) to my TestContoller(), so that it looks like this:

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?


回答1:


  • 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.
  • If you do use null layout then you are fully responsible for setting the size and location of all components added to that container.
  • Your current problem is that you never give TestView a size or location and have then added it to a null layout-using container.
  • You shouldn't add a component (above, your JComboBox) to more than one container.
  • Don't call setVisible(true) on the JFrame until after you've added all components and called pack() on it.

e.g.,

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:

'Almost never'? In which cases you would use it [the null layout]?

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



来源:https://stackoverflow.com/questions/13749654/component-on-jpanel-not-showing-when-setlayoutnull

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!