Why can't BoxLayout be used while FlowLayout can?

I am confused by the following.

Case A

  • Set the layout manager for JFrame as BoxLayout.
  • Add JButton to the JFrame container.
  • Compile
  • Run
  • Exception: "Exception in thread" AWT-EventQueue-0 "java.awt.AWTError: BoxLayout cannot be shared"

Case B

  • Set the layout manager for JFrame as FlowLayout.
  • Add JButton to the JFrame container.
  • Compile
  • Run
  • An exception is thrown.

Why is Case A throwing an exception and Case B not? Why do FlowLayout and BoxLayout behave differently in this regard? What does this mean in case A using BoxLayout cannot be shared?

I read several similar threads on this website about this exception message, but I am still confused when compared to FlowLayout and what the exception message means for sure.

+5
source share
1 answer

Simple answer

Basically, "BoxLayout can't be shared" in this situation means that you are trying to make your JFrame and its contentPane() common BoxLayout tag.


Extended explanation

When setting a Layout for a JFrame it implicitly calls getContentPane().setLayout(manager) , so you are actually setting the layout for contentPane (), not the frame itself.

This leads us to see how containers are checked inside BoxLayout and FlowLayout .


FlowLayout

There is no constructor in this layout that will accept the container as a parameter and, therefore, the container will not be considered when creating the object. This class does not have a container class.

BoxLayout

BoxLayout contrast, has a constructor that takes a container as a parameter and stores it in the target instance variable. This is done to check it later in the layoutContainer(container) method. It has a checkContainer(container) method that will check whether the instance variable matches the container specified in the parameter. It throws a throw new AWTError("BoxLayout can't be shared"); if it is not.


This was an introduction to the following explanation.

As stated in the first paragraph, JFrame.setLayout(LayoutManager) will call JFrame.getContentPane().setLayout(LayoutManager) , and thus Layout set by default to contentPane() , which is JPanel .

Check out the BoxLayout(container, int) constructor and ask yourself:

Now I know that the layout is set to JPanel ( contentPane() ) and not the JFrame itself, what parameter will I give to this constructor?

Is it a good idea to give yourself a JFrame ? Knowing that this is not the component that was installed on the layout?

Answer: this, of course, is not a good idea.

Here is the right way to achieve this:

 JFrame frame = new JFrame(); frame.setLayout(new BoxLayout(frame.getContentPane(), ...); 

Why?

Since we now know that the container is contentPane() , and that, ultimately, when adding a component, for example, verification will occur, and the parameter inside the constructor should be exactly the same object as the component, where it is set on Layout that happens to FlowLayout for example.


Sources

BoxLayout

FlowLayout

+4
source

Source: https://habr.com/ru/post/1236492/


All Articles