confused with LayoutManagement: JSplitPane

A

Andreas Leitgeb

I've got difficulties with JSplitPane:
Some dialog consist of four parts (vertically), with sliders between each.
That was created by a colleague with netbean's form-editor, and works almost
ok. There is one master-JSplitPane, and two inner JSplitPanes and inside
that are the actual components.

Now, "they" want a special behaviour: if the bottom-most component
is hidden (with slider's arrow-buttons on windows), then the other
three components should all grow to fill the available screen-estate,
and if the last one is made visible again, then all the other ones
should shrink equally a little to make room for the last one.

I'm a bit at loss. It seems to do a lot already on closing/reopening
that last part. Things that I can only assume is implemented in the
JSplitPane (as I didn't implement it myself; perhaps that goes auto-
magically based on Components' preferred- and minimum sizes), but it
doesn't propagate that extra space to the upper sibling in the master
JSplitPane. I.e.: only the upper component of the lower inner JSplitPane
gets all the extra space.

How would I better arrange or tweak those SplitPanes such that size-
propagation among the other Components works more "natural"?

I tried to become friends with netbeans, but netbeans obviously refused
my friends-request and misunderstood all my attempts at dragging
components around in the form-editor to the point that even repeated
"undo" didn't restore the old state, but only exiting and restarting
netbeans did. In the end, if I have to restructure the hierachy, I'll
probably have to hand-edit the .form file as well for it to remain
consistent with the .java, in case future colleagues will want to edit
that dialog after me and to whom netbeans is more cooperative.
(freshly installed netbeans 6.1.7 here)
 
M

markspace

Andreas said:
How would I better arrange or tweak those SplitPanes such that size-
propagation among the other Components works more "natural"?


I think it depends on the type of LayoutManager your component uses.
Are you allowed to post the code you colleague wrote? Is NetBeans using
its default layout manager (GroupLayout, I think)?

I tried to become friends with netbeans, but netbeans obviously refused
my friends-request and misunderstood all my attempts at dragging


This is funny stuff.

Old timers trick:

You have to write a complicated procedure in assemble language.
Solution: start with C, generate the assembly language source file, then
toss the C code and hand edit the assembly.

In the same way, I think you're going to have to muck with the generated
code that Matisse (NetBeans) makes for you. You might try making a
three panel form on your own, note what constraints Matisse uses, then
create a method to swap between those two configurations.

This is basically the same as adding (or removing) a component to a
different layout manager, like FlowLayout or BoxLayout, except
GroupLayout probably has more constraints that GridBagLayout and will be
a pain to work with. On the bright side if you reuse the code Matisse
generates you only have the one split pane to mess with.


An SSCCE would help immensely. If you can, post the form file that
Matisse generates as well.
 
K

Knute Johnson

Andreas said:
I've got difficulties with JSplitPane:
Some dialog consist of four parts (vertically), with sliders between each.
That was created by a colleague with netbean's form-editor, and works almost
ok. There is one master-JSplitPane, and two inner JSplitPanes and inside
that are the actual components.

Now, "they" want a special behaviour: if the bottom-most component
is hidden (with slider's arrow-buttons on windows), then the other
three components should all grow to fill the available screen-estate,
and if the last one is made visible again, then all the other ones
should shrink equally a little to make room for the last one.

Do they want the sliders between to move?
I'm a bit at loss. It seems to do a lot already on closing/reopening
that last part. Things that I can only assume is implemented in the
JSplitPane (as I didn't implement it myself; perhaps that goes auto-
magically based on Components' preferred- and minimum sizes), but it
doesn't propagate that extra space to the upper sibling in the master
JSplitPane. I.e.: only the upper component of the lower inner JSplitPane
gets all the extra space.

How would I better arrange or tweak those SplitPanes such that size-
propagation among the other Components works more "natural"?

I tried to become friends with netbeans, but netbeans obviously refused
my friends-request and misunderstood all my attempts at dragging
components around in the form-editor to the point that even repeated
"undo" didn't restore the old state, but only exiting and restarting
netbeans did. In the end, if I have to restructure the hierachy, I'll
probably have to hand-edit the .form file as well for it to remain
consistent with the .java, in case future colleagues will want to edit
that dialog after me and to whom netbeans is more cooperative.
(freshly installed netbeans 6.1.7 here)
 
A

Andreas Leitgeb

markspace said:
I think it depends on the type of LayoutManager your component uses.

The inner LayoutManager works well (as seen when manually resizing it)
and also sets sane Preferred- and MinimumSizes. For the sake of my
problem I think we could just as well assume it were JButtons.

Meanwhile I understand some of netbeans misunderstandings...
I was irritated by some component added in one but not the other
parts, that had no use at all, and was later replaced, anyway.
As it seems, the colleague who did that wasn't really friend with
netbeans, either.
Old timers trick:
You have to write a complicated procedure in assemble language.
Solution: start with C, generate the assembly language source file, then
toss the C code and hand edit the assembly.

I get the point :)
This is basically the same as adding (or removing) a component to a
different layout manager, ...

That last component isn't really to be removed/added dynamically, but
only invisibilized by its slider sticking at the bottom of that particular
JSplitPane, so the user can "restore" it using the slider.
 
A

Andreas Leitgeb

Knute Johnson said:
Do they want the sliders between to move?

Yes, of course the sliders all have to move for the components to change
size as requested.

E.g. if normally each of the 4 component has an extent of 300 pixels
in the relevant direction, and then the last one is hidden, then the
remaining ones should grow to 400 pixels to compensate for the space
left behind by the last one, and if the user clicks on the slider-
button to make that last one visible again, then all the components
should settle at 300 pixels again, unless the user sets other sizes.

Up to a few questions (which I'll ask in a new thread), I think I mostly
understand the mechanics of a single JSplitPane. It's the cascading of
multiple JSplitPanes that still troubles me.
 
A

Andreas Leitgeb

Andreas Leitgeb said:
I've got difficulties with JSplitPane:

After my decision to ignore/discard that netbeans-generated
..form file I've come a good step further. However, I don't
find this explained in the JavaDoc of JSplitPane, nor in the
tutorial:

I'd like the slider to initially come up, as if the user had
clicked the "to-bottom" button in the slider. If the user then
clicks the "to-top"-button, then the slider should return to
default-position (just as it does if the user had manually
clicked "to bottom" first, just that this "to bottom" should
happen automatically.)

PS: setOneTouchExpandable(true) is explicitly set for all the
relevant JSplitPanes in that dialog.
 
M

markspace

Andreas said:
That last component isn't really to be removed/added dynamically, but
only invisibilized by its slider sticking at the bottom of that particular
JSplitPane, so the user can "restore" it using the slider.


Now I'm confused. Is this desired behavior, or not? If you can make an
SSCCE, I think that would help a lot.
 
K

Knute Johnson

Andreas said:
Yes, of course the sliders all have to move for the components to change
size as requested.

E.g. if normally each of the 4 component has an extent of 300 pixels
in the relevant direction, and then the last one is hidden, then the
remaining ones should grow to 400 pixels to compensate for the space
left behind by the last one, and if the user clicks on the slider-
button to make that last one visible again, then all the components
should settle at 300 pixels again, unless the user sets other sizes.

Up to a few questions (which I'll ask in a new thread), I think I mostly
understand the mechanics of a single JSplitPane. It's the cascading of
multiple JSplitPanes that still troubles me.

I'm sorry, it's just not clear to me what you are trying to do. Maybe
an SSCCE would help?
 
A

Andreas Leitgeb

Knute Johnson said:
I'm sorry, it's just not clear to me what you are trying to do. Maybe
an SSCCE would help?

I don't see, how an SSCCE would help in this particular situation.
SSCCE's are, if I see some behaviour that I don't want and cannot
explain.

In my case I *want* some particular behaviour, and if I could code
that behaviour into an SSCCE, I wouldn't need to ask the question
in the first place. Since I do not yet know how to code that
behaviour, I'm still bound to describe it, and I can't see how
anyone would understand my description better, just because they
now have a window with a particular layout that behaves some
other way.

I'll try it now some other way. Giving names to things often
helps, afterall.

That's the layout:
JSplitPane jsp1=new JSplitPane()
JSplitPane jsp2=new JSplitPane()
JSplitPane jsp3=new JSplitPane()
jsp1.add(jsp2); jsp1.add(jsp3);
jsp2.add(comp1); jsp2.add(comp2);
jsp3.add(comp3); jsp3.add(comp4);

Each of the components comp1-comp4 can be assumed to have
reasonable (and in my case non-zero) minimum and preferred
sizes.

What I'm after in this thread is: if the user uses those
little arrow-buttons in jsp3's splitter to minimize(hide) comp4,
then (rather than comp3 alone growing for the freed space) I'd
like all comp1,comp2 and comp3 to grow equally. For this, the
jsp3 would have to inform jsp1 of a reduced preferred size
(which of course isn't standard behaviour of splitpanes), and
let jsp1 rearrange the space among it's child splitpanes, so
in the end comp1, comp2 and comp3 are equal-sized and together
consume the same screenspace as did comp1-comp4 before the user's
action.

Maybe I'm missing something obvious, but I don't see where
and how I could add a callback to be informed of user clicking
those minimize-buttons in the splitter.
 
K

Knute Johnson

Andreas said:
I don't see, how an SSCCE would help in this particular situation.
SSCCE's are, if I see some behaviour that I don't want and cannot
explain.

In my case I *want* some particular behaviour, and if I could code
that behaviour into an SSCCE, I wouldn't need to ask the question
in the first place. Since I do not yet know how to code that
behaviour, I'm still bound to describe it, and I can't see how
anyone would understand my description better, just because they
now have a window with a particular layout that behaves some
other way.

I'll try it now some other way. Giving names to things often
helps, afterall.

That's the layout:
JSplitPane jsp1=new JSplitPane()
JSplitPane jsp2=new JSplitPane()
JSplitPane jsp3=new JSplitPane()
jsp1.add(jsp2); jsp1.add(jsp3);
jsp2.add(comp1); jsp2.add(comp2);
jsp3.add(comp3); jsp3.add(comp4);

Each of the components comp1-comp4 can be assumed to have
reasonable (and in my case non-zero) minimum and preferred
sizes.

What I'm after in this thread is: if the user uses those
little arrow-buttons in jsp3's splitter to minimize(hide) comp4,
then (rather than comp3 alone growing for the freed space) I'd
like all comp1,comp2 and comp3 to grow equally. For this, the
jsp3 would have to inform jsp1 of a reduced preferred size
(which of course isn't standard behaviour of splitpanes), and
let jsp1 rearrange the space among it's child splitpanes, so
in the end comp1, comp2 and comp3 are equal-sized and together
consume the same screenspace as did comp1-comp4 before the user's
action.

Maybe I'm missing something obvious, but I don't see where
and how I could add a callback to be informed of user clicking
those minimize-buttons in the splitter.

OK, I think I understand what you want to do now. The only way I can
think to approach this is to use a ComponentListener and snag resize
events. Adjust the middle divider according to the percentage of window
covering the hidden component. It's a tricky one for sure.
 
A

Andreas Leitgeb

Patricia Shanahan said:
You could write an SSCCE that exhibits the behavior you don't like, and
explain what is wrong in terms of what that application does. That would
give people a test case for experiments.

Ok, convinced me, and sorry for taking so long for it...

Notes:
- I'm really a newbie to Java *GUI* programming and haven't
yet found how to exit the app on Alt-F4. Therefore
the java-process needs to be killed separately afterwards.
(My actual program is an Applet, so I don't have the problem
there.) I guess it's just a question of adding some Listener
that calls some exit-method somewhere...
- What I want here is obviously pushing JSplitPane's envelope.
I quite likely will need some more own code in Listeners to
add at various places.

What I like/dislike in current behaviour:
- initially the last component is now hidden (good)
- but the third one takes double space instead (bad)
I'd like the space to be equally shared among the visible ones.
- if I enlarge the frame (or move the middle slider), it unminimizes
comp4 to its minimumSize (bad) (this doesn't happen if comp4
had been manually minimized, despite its non-zero minimumSize.)
How do I get comp4 initially minimized such that it doesn't re-
appear on resizes from the outside?
- If instead comp4 is initially unminimized, and then the middle
slider is moved (a little), the other sliders stay where they
are (a result of the rather strange resizeWeights) (good)
Otoh, it impedes proper equal resizing of the components (bad),
so it is just a limited quality workaround.
- I can move the middle slider further and push away the other ones,
but with the other ones, I cannot push the middle slider. This
is logical behaviour from implementation POV, but unlogical for
the user. (bad)
- Creating a 4-pane consistent MegaSplitPane from normal SplitPanes
likely isn't a trivial thing, but perhaps some aspects are easier
to fix than by a full rewrite of SplitPane and its plaf.

Finally, here is the code:
for easy retrieval from www:
http://www.logic.at/people/avl/stuff/LayoutDemo.java

and inline for easier discussion:
(please don't comment on style - it's an SSCCE, not a model)
-----snip to end----
import java.awt.Dimension;
import javax.swing.*;

public class LayoutDemo extends JFrame {
private JSplitPane[] jsps=new JSplitPane[3];
private JButton[] jbs=new JButton[4];

public LayoutDemo() {
for (int i=0;i<4;i++) {
JButton jb=jbs=new JButton("comp"+(i+1));
jb.setMinimumSize(new Dimension(50,50));
jb.setPreferredSize(new Dimension(150,150));
}

// this one is nice for moving the middle slider:
final double rw[]= { 0.0, 0.5, 1.0 };

for (int i=0;i<3;i++) {
JSplitPane jsp=jsps=new JSplitPane();
jsp.setOneTouchExpandable(true);
jsp.setResizeWeight( rw );
jsp.setContinuousLayout( true );
}

jsps[0].setLeftComponent(jbs[0]);
jsps[0].setRightComponent(jbs[1]);
jsps[1].setLeftComponent(jsps[0]);
jsps[1].setRightComponent(jsps[2]);
jsps[2].setLeftComponent(jbs[2]);
jsps[2].setRightComponent(jbs[3]);

jsps[2].setDividerLocation(10000);
jsps[2].setLastDividerLocation(-1);

getContentPane().add(jsps[1], java.awt.BorderLayout.CENTER);
pack();

setSize(700,200);
setVisible(true);
}

public static void main(String args[]) {
new LayoutDemo();
}
}
 
J

John B. Matthews

[...]
- I'm really a newbie to Java *GUI* programming and haven't
yet found how to exit the app on Alt-F4. Therefore
the java-process needs to be killed separately afterwards.
(My actual program is an Applet, so I don't have the problem
there.) I guess it's just a question of adding some Listener
that calls some exit-method somewhere...

I'm not sure about Alt-F4, but you can set the JFrame's default close
operation in the constructor:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

[...]
- if I enlarge the frame (or move the middle slider), it unminimizes
comp4 to its minimumSize (bad) (this doesn't happen if comp4
had been manually minimized, despite its non-zero minimumSize.)
How do I get comp4 initially minimized such that it doesn't re-
appear on resizes from the outside?

Give the last component a preferred size of zero:

jbs[3].setMinimumSize(new Dimension(0,0));

Sorry, I'm not sure about the other stuff.
 
A

Andreas Leitgeb

John B. Matthews said:
I'm not sure about Alt-F4, but you can set the JFrame's default close
operation in the constructor:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Thanks! Yes, that works also for Alt-F4. Surely for any keycombo
that one's WM has bound to closing a window. In hindsight it seems
so obvious, that I grumble at myself for not having had a look at
javadoc for JFrame, but only for JSplitPane ...
- if I enlarge the frame (or move the middle slider), it unminimizes
comp4 to its minimumSize (bad) (this doesn't happen if comp4
had been manually minimized, despite its non-zero minimumSize.)
Give the last component a preferred size of zero:
jbs[3].setMinimumSize(new Dimension(0,0));

That's of course the obvious "workaround", but the problem is, that setting
the dividerLocation to a large value just is not the same as the effect of
user pressing the maximize button. If I set the minimumSize to 0,0 then
the difference still shows up somewhere else - like when the splitpane
itself is resized and had a resizeWeight < 1.0, then upon enlargening
the splitpane the supposedly minimized window would still reappear.
In the example, set minimumSize to 0,0 and the rw[] to {0.5,0.5,0.5}
then recompile/run and move the middle slider to the left a bit.

I appreciate your intention to help on this one.
 
A

Andreas Leitgeb

RedGrittyBrick said:

That covers the standard features of JSplitPane, which my demands seem
to leave far behind.
Even the nested example is one, where the inner splitpane has a different
orientation from the outer one, and the problems I have with nesting
equally-oriented splitpanes do not show up there.

Thanks anyway for trying to help.

PS: Meanwhile I've posted an SSCCE.
 
A

Andreas Leitgeb

Andreas Leitgeb said:
That covers the standard features of JSplitPane, which my demands seem
to leave far behind.

oops, forget that posting, please ... I missed the link about
propertyChange listening, which surely is the key to customized
behaviour as I'd like. I'll see what I can do with it.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top