The container does not resize after running validation

After manually replacing the components via add and remove I call validate() in the container. According to the documentation,

The verification method is used to make the container lay out its subcomponents again . It should be called when this container subcomponents are modified (added or removed from the container or information related to the layout) after the container has been displayed.

The phrase “lay out its subcomponents again” makes me think that the container will change accordingly, but it’s not. Instead, after calling validate() , I need to also call pack() to see all of its subcomponents.

Why is this? Am I doing something wrong?

+3
source share
3 answers

(perhaps due to this ambiguity, the description changes to the latest javaDoc )

JavaDoc 7 NOT talking

The verification method is used to have the container lay out its subcomponents again ..

therefore, it will only compose the components, whereas you will need pack() .

Note that pack () clearly says

Causes this window to be sized to fit the preferred sizes and layouts of its subcomponents.

+5
source

I think you yourself answered your question, I hope this demonstration helps you

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.LineBorder; public class AddComponentsAtRuntime { private JFrame f; private JPanel panel; private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack; public AddComponentsAtRuntime() { JButton b = new JButton(); b.setBackground(Color.red); b.setBorder(new LineBorder(Color.black, 2)); b.setPreferredSize(new Dimension(600, 10)); panel = new JPanel(new GridLayout(0, 1)); panel.add(b); f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(panel, "Center"); f.add(getCheckBoxPanel(), "South"); f.setLocation(200, 200); f.pack(); f.setVisible(true); } private JPanel getCheckBoxPanel() { checkValidate = new JCheckBox("validate"); checkValidate.setSelected(false); checkReValidate = new JCheckBox("revalidate"); checkReValidate.setSelected(false); checkRepaint = new JCheckBox("repaint"); checkRepaint.setSelected(false); checkPack = new JCheckBox("pack"); checkPack.setSelected(false); JButton addComp = new JButton("Add New One"); addComp.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JButton b = new JButton(); b.setBackground(Color.red); b.setBorder(new LineBorder(Color.black, 2)); b.setPreferredSize(new Dimension(600, 10)); panel.add(b); makeChange(); System.out.println(" Components Count after Adds :" + panel.getComponentCount()); } }); JButton removeComp = new JButton("Remove One"); removeComp.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int count = panel.getComponentCount(); if (count > 0) { panel.remove(0); } makeChange(); System.out.println(" Components Count after Removes :" + panel.getComponentCount()); } }); JPanel panel2 = new JPanel(); panel2.add(checkValidate); panel2.add(checkReValidate); panel2.add(checkRepaint); panel2.add(checkPack); panel2.add(addComp); panel2.add(removeComp); return panel2; } private void makeChange() { if (checkValidate.isSelected()) { panel.validate(); } if (checkReValidate.isSelected()) { panel.revalidate(); } if (checkRepaint.isSelected()) { panel.repaint(); } if (checkPack.isSelected()) { f.pack(); } } public static void main(String[] args) { AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime(); } } 
+7
source

The main, but subtle assumption here is: the layout and size are directly related to 1-to-1. This is not the case, and is a common assumption in Swing programming. Size is the result of layout and size restrictions.

Layout:

  • Within the space limits you specified
  • And given the components that I need to fit into this space
  • Place these components in relation to each other according to the specified strategy (BoxLayout, BorderLayout, etc.).

If the LayoutManager can match the components that you provided to it, without changing the overall size of the container, it will not resize the container. On the other hand, calling pack is an explicit request to minimize the amount of space used . This is the main reason you see the results.

Some things you can try:

  • Make sure you set the maximum size on your components / containers, which will force restrictions on the size of the components when re-executing the layout.
  • Always call pack () as a habit
  • Try some suggestions regarding common placement issues.

This is difficult with Swing because you need to understand the outline of the drawing, layout managers, and some details of the window system. When it comes to the Swing documentation (and all the methods and several different ways to do one thing), I try to read the documentation with the “don't accept anything” approach, that is, “What is the least possible thing that this documentation method implies that it can do it, "and if you do not observe additional behavior, do not be fooled into thinking that he is doing more.

Finally, I would add that the work of the LayoutManager as a whole is not to determine the size of the containers, but to place the components in some relation to each other in accordance with the layout of the strategy (this is discussed in the additional information here ). The idea is that with the correct LayoutManager, you specify the basic layout of the strategy , and as a result, when you resize the window, the LayoutManager will intelligently move components around so that your user interface continues to follow this general strategy. Thus, layouts are mainly intended for regardless of the total size of the space in which they work, so they try not to make assumptions about what kind of space is available, instead they take the size that they specify and try to do what makes sense. Unless you explicitly set size limits for your components, you cannot guarantee what size they will be.

This means that if the LayoutManager does not consider that it needs to be resized to fit its overall strategy, it will not basically resize it . On the other hand, calling pack is an explicit request to collect data and remove unnecessary space.

+2
source

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


All Articles