Skip to main content

Incorrect behavior of JXCollapsiblePane when used with MigLayout 'grow' constraint

11 replies [Last post]
sbozian
Offline
Joined: 2010-08-30
Points: 0

Assume you are using a collapsible panel of type JXCollapsiblePane inside any container (say JXPanel or JXFrame) whose layout manager is of type MigLayout. The problem appears whenever you use the 'grow' MigLayout constraint on the collapsible panel. Ideally, when 'grow' is specified for a component, this component would claim all available space in the cell in which it is added. Now, while this works perfectly well with other components, it doesn't work properly when used with a collapsible panel. What happens is that the panel does no longer collapse/expand properly, and a strange behavior may be observed depending on the current window size, etc.

To reproduce the problem, run the example below which consists of a JXFrame whose layout is set to MigLayout. The frame contains from top to bottom: a collapsible panel (row 1), a 'Collapse' button (row 2), an 'Expand' button (row 3), and an ordinary panel (row 4). In addition to using it for the collapsible panel (row 1), I used 'grow' on purpose with the 'Expand' button (row 3) and the ordinary panel (row 4), in order to illustrate how 'grow' should ideally behave.

A first workaround which I found was to set the panel to invisible (such that it does not claim any space) when collapsed. But with that, the animation on collapse wouldn't show anymore. My goal is to be able to use a collapsible panel with a 'grow'-like layout constraint. The panel should take the 'grow' effect when expanded, but should still be able to entirely collapse, without claiming any space in collapse mode. So if you suggest using some other layout manager which can offer the same feature with correct behavior, it would also be great.

Finally, after inspecting the implementation of JXCollapsiblePane.setCollapsed(boolean val), I found that changing the value of the second argument (the delta) in 'new AnimationParams(30, Math.max(8, dimension / 10), 1.0f, 0.01f);' is affecting to what extent the collapsible panel is collapsing, although my first impression was it is only related to the animation, or the speed of the animation. So some clarification on how this 'delta' is exactly used and why it is affecting the way the panel is collapsed is also highly appreciated.

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextField;

import javax.swing.border.TitledBorder;

import net.miginfocom.swing.MigLayout;

import org.jdesktop.swingx.JXCollapsiblePane;

import org.jdesktop.swingx.JXFrame;

public class JXCollapsiblePaneWithMigLayout {

private static JXFrame frame;

private static JXCollapsiblePane collapsiblePane;

public static void main(String[] args) {

collapsiblePane = new JXCollapsiblePane();

collapsiblePane.setLayout(new MigLayout("fill, insets 0 0 0 0"));

collapsiblePane.add(new JLabel("Search:"), "cell 0 0");

collapsiblePane.add(new JTextField(10), "cell 1 0");

collapsiblePane.add(new JButton("Refresh"), "cell 2 0");

collapsiblePane.setBorder(new TitledBorder("Filters"));

JButton collapseBtn = new JButton("Collapse");

collapseBtn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

collapsiblePane.setCollapsed(true);

}

});

JButton expandBtn = new JButton("Expand");

expandBtn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

collapsiblePane.setCollapsed(false);

}

});

frame = new JXFrame();

frame.setLayout(new MigLayout("fill, insets 0 0 0 0"));

frame.add(collapsiblePane, "grow, cell 0 0");

frame.add(collapseBtn, "cell 0 1");

frame.add(expandBtn, "grow, cell 0 2");

JPanel panel = new JPanel();

panel.setBorder(new TitledBorder("Panel with Grow MigLayout Constraint"));

frame.add(panel, "grow, cell 0 3");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);;

frame.pack();

frame.setVisible(true);

}

Thanks,

Shant

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kschaefe
Offline
Joined: 2006-06-08
Points: 0

Please read the documentation for JXCollisplePane.  This is not a bug, but an imcopatibility.  JXCollapsiblePane does not work with layout managers that do not respect the component's preferred size (as MIGLayout does in grow mode).

Karl

kleopatra
Offline
Joined: 2003-06-11
Points: 0

hmm ... sounds like a weird requirement, should work with whatever sizing, IMO

Cheers

Jeanette

 

kschaefe
Offline
Joined: 2006-06-08
Points: 0

I guess we could try to make the viewport shrink without doing preferred size tricks, but then what do we do with the extra space?  How do we actually shrink?

Karl

sbozian
Offline
Joined: 2010-08-30
Points: 0

Thank you for your replies.

So.. any suggestion on how to make the collapsible panel "grow" i.e. fill the whole space (say a layout cell) on expand, and shrink on collapse?

Thanks,
Shant

kschaefe
Offline
Joined: 2006-06-08
Points: 0

Place it in a JPanel with a BorderLayout and attach it to a directional.  The center will be given the extra space.

Karl

sbozian
Offline
Joined: 2010-08-30
Points: 0

Hi Karl,

Not sure if I got what you meant.

Did you mean: place the collapsible panel inside a JPanel whose layout is set to BorderLayout, with the BorderLayout.CENTER constraint?

JPanel panel = new JPanel();

panel.setLayout(new BorderLayout());

panel.add(collapsiblePane, BorderLayout.CENTER);

Is that what you meant by "attach it to a directional"?

If that's what you meant, please check the following example. The same problem still occurs.

As you mentioned, when using BorderLayout, whatever is placed in BorderLayout.CENTER is occupying all available space, exactly like "grow" does, which is exactly why the collapsing/expanding feature of the panel is being once again corrupted. So for example, in this case, the collapsible panel behaves properly only when placed in BorderLayout.NORTH or BorderLayout.SOUTH which do not provide the "grow" effect I was looking for.

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.JButton;

import javax.swing.JPanel;

import javax.swing.border.TitledBorder;

import org.jdesktop.swingx.JXCollapsiblePane;

import org.jdesktop.swingx.JXFrame;

public class JXCollapsiblePaneWithBorderLayout {

private static JXFrame frame;

private static JXCollapsiblePane collapsiblePane;

public static void main(String[] args) {

collapsiblePane = new JXCollapsiblePane();

collapsiblePane.setBorder(new TitledBorder("Filters"));

JButton collapseBtn = new JButton("Collapse");

collapseBtn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

collapsiblePane.setCollapsed(true);

}

});

JButton expandBtn = new JButton("Expand");

expandBtn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

collapsiblePane.setCollapsed(false);

}

});

JPanel panel = new JPanel();

panel.setLayout(new BorderLayout());

panel.add(collapsiblePane, BorderLayout.CENTER);

panel.add(collapseBtn, BorderLayout.NORTH);

panel.add(expandBtn, BorderLayout.SOUTH);

frame = new JXFrame();

frame.add(panel);

frame.pack();

frame.setVisible(true);

}

}

Thanks,

Shant

kschaefe
Offline
Joined: 2006-06-08
Points: 0

BorderLayout CENTER will not respect preferred size, but the directionals (NORTH, SOUTH, EAST, WEST) do.

Karl

sbozian
Offline
Joined: 2010-08-30
Points: 0

Hi Karl,

True. I can see that. But looks like we're stuck in a loop. :S

Your suggestion was supposed to "make the collapsible panel grow on expand and shrink on collapse" right? Otherwise what's my benefit of using BorderLayout with one of the directionals (NORTH, SOUTH, EAST, WEST), when I can still use MIGLayout without specifying "grow"?

So again.. any suggestion on how to make the collapsible panel "grow" i.e. fill the whole space (say a layout cell) on expand, and shrink on collapse?

Thanks,

Shant

sbozian
Offline
Joined: 2010-08-30
Points: 0

Hi again,

I have already mentioned in my first post that a possible workaround is to set the panel to invisible when collapsed. As a matter of fact, if I compare an old version of Swingx I have with the latest one, I can see that the "setCollapsed(boolean val)" implementation now contains calls to "setVisible" to show/hide the panel, calls that were not present in the old version. This is why, while the "grow" problem I described occurs in the old verison with and without animation, it is solved in the new version if animation is disabled. This is due to the added line "wrapper.getView().setVisible(!collapsed);" in the case without animation.

So we can conclude that with the new version of Swingx, the collapsible panel problem I described in this forum occurs only if animation is enabled. And I already mentioned that changing the value of the second argument (the delta) in 'new AnimationParams(30, Math.max(8, dimension / 10), 1.0f, 0.01f);' is affecting to what extent the collapsible panel is collapsing. For example, When the "delta" is set to "dimension" instead, the collapsible panel collapses completely as it should, however the animation becomes very fast.

So can you help me understand how should I use this "delta"?

Thanks,
Shant

kschaefe
Offline
Joined: 2006-06-08
Points: 0

Shant,

That would not be the correct solution.  However, I think we may be able to change what we're setting the preferred size of.  If instead of monkeying with the preferred size of the JXCollapsiblePane, we change the preferred size of the internal JViewport we have the same effect, but it should work for this grow case.

Please file a bug report ad I will try toying with this idea.

Karl

sbozian
Offline
Joined: 2010-08-30
Points: 0

Hi Karl,

Thanks a lot for your help. I just created issue SWINGX-1461 in this regard.

Thanks again,
Shant