how to set (preferred) JSlider length?

M

Mark_Galeck

Hello, I want to set a length of a horizontal JSlider myself, and
then let the layout manager figure out lay everything out keeping my
length if it can figure out how. Some people say I should not set
sizes myself, but in this situation, letting the manager decide, I
think this is OK?

Anyway, I am not succeeding at all - here is my code boiled down to
the bare minimum - here I am not even using any layout manager. Here
is the JApplet init() method:

public void init() {
JSlider s = new JSlider(0, 400);
add(s);
validate();
Dimension d = s.getSize();
d.width = 400;
s.setSize(d);
validate();
}

I try to do it twice, first in the constructor, then I validate() to
make sure it is really laid out initially, so I can call getSize and
get a meaningful result and then change it and call setSize.

My applet window size is 1000x1000. In the example above, I try first
without a layout manager. Then the slider size is 1000 as well, in
the middle of the applet.

OK - If I try, for example, to use BorderLayout and then first add to
Center, another component, and then this slider to the East - that I
thought would make the center as large as possible (this is how
BorderLayout works) and restrict the slider to the smallest size
possible, so now I hoped the slider would be 400 pixels wide and the
central component 600. No - the center is about 800 and the slider -
200.

What is going on here? Why can't I do this? How??

Please explain to me. Thank you very much! Mark
 
M

Mark_Galeck

Here is the file foo.java:

import javax.swing.*;
import java.awt.*;

public class foo extends JApplet {
public void init() {
setLayout(new BorderLayout());
add("Center", new JPanel());
JSlider s = new JSlider(0, 400);
add("East", s);
validate();
Dimension d = s.getSize();
d.width = 400;
s.setSize(d);
validate();
}
}

Here is the file foo.html:


<OBJECT
codetype="application/java"
code=foo.class
width=1024 height=1024
<PARAM NAME="cache_option" VALUE="No">

</OBJECT>



OK, then why is the slider 200 pixels wide, not 400???? Please
explain, thank you! Mark
 
T

tomaszewski.p

Here is the file foo.java:

import javax.swing.*;
import java.awt.*;

public class foo extends JApplet {
        public void init() {
                setLayout(new BorderLayout());
                add("Center", new JPanel());
                JSlider s = new JSlider(0, 400);
                add("East", s);
                validate();
                Dimension d = s.getSize();
                d.width = 400;
                s.setSize(d);
                validate();
        }
        }

Here is the file foo.html:

<OBJECT
                codetype="application/java"
         code=foo.class
                width=1024 height=1024



<PARAM NAME="cache_option" VALUE="No">

</OBJECT>

OK, then why is the slider 200 pixels wide, not 400???? Please
explain, thank you!  Mark

Try this:

public void init() {
JSlider s = new JSlider(0, 400);
add(s);
s.setPreferredSize(new Dimension(400, 20));
}


Przemek
 
M

Mark_Galeck

Nope, same thing as always, slider length is 1024 (covers the whole
applet).
 
K

Knute Johnson

Mark_Galeck said:
Nope, same thing as always, slider length is 1024 (covers the whole
applet).

Change the layout manager to something that honors preferred size.

My preference is GridBagLayout.

knute...
 
M

Mark_Galeck

Change the layout manager to something that honors preferred size.

My preference is GridBagLayout.


same problem, does not honor, heres the code foo.java , width is 200
not 400

import javax.swing.*;
import java.awt.*;

public class foo extends JApplet {
public void init() {
GridBagConstraints gridBagConstraints;

setLayout(new GridBagLayout());

gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.weightx = 1.0;
add(new JPanel(), gridBagConstraints);

gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
JSlider s = new JSlider(0, 400);
add(s, gridBagConstraints);
validate();
Dimension d = s.getSize();
d.width = 400;
s.setSize(d);
validate();
}
}
 
J

John B. Matthews

[...]

Sorry, I overlooked the applet requirement, but this seems to work:

import java.awt.*;
import javax.swing.*;

/**
* JSliderTest1
* @author John B. Matthews
*/
public class JSliderTest1 extends JPanel {

public static void main(String args[]) {
JFrame frame = new JFrame("Slider!");
frame.setContentPane(new JSliderTest1());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 200);
frame.setVisible(true);
}

public JSliderTest1() {
this.setLayout(new BorderLayout());
this.add(new JLabel("West"), BorderLayout.WEST);
this.add(new JLabel("North", JLabel.CENTER), BorderLayout.NORTH);
this.add(genSliderPanel(), BorderLayout.CENTER);
this.add(new JLabel("South", JLabel.CENTER), BorderLayout.SOUTH);
this.add(new JLabel("East"), BorderLayout.EAST);
}

private JPanel genSliderPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JSlider slider = new JSlider();
slider.setMaximumSize(new Dimension(400, Short.MAX_VALUE));
panel.add(Box.createVerticalGlue());
panel.add(slider);
panel.add(Box.createVerticalGlue());
return panel;
}
}
 
M

Mark_Galeck

Well, this only works if I add the slider to the CENTER of the
BorderLayout. If I add a Panel to the center, and the slider to the
EAST, does not work anymore - slider still size 200
 
D

Daniele Futtorovic

Well, this only works if I add the slider to the CENTER of the
BorderLayout. If I add a Panel to the center, and the slider to the
EAST, does not work anymore - slider still size 200

Use setPreferredSize(), not setSize(). The LayoutManager will use
setSize(). No wonder it has no effect in your code.

If you use a GridBagLayout (my LayoutManager of choice, too, but tricky
for beginners):
put weightx > 0
DO NOT use fill = HORIZONTAL, but rather fill = NONE
figure out the anchor yourself.

Once again: DO NOT invoke setSize() if you're using LayoutManagers. Not
that it's bad -- it's pointless.
Play around with setPreferredSize, setMinimumSize and setMaximumSize
instead.
 
J

John B. Matthews

Mark_Galeck said:
Well, this only works if I add the slider to the CENTER of the
BorderLayout. If I add a Panel to the center, and the slider to the
EAST, does not work anymore - slider still size 200

Would a vertical slider do in the east? Would JSpinner be an
alternative? As BorderLayout's "EAST and WEST components may be
stretched vertically," why not set the slider's minimum size and let it
grow larger?

<http://java.sun.com/javase/6/docs/api/java/awt/BorderLayout.html>

import java.awt.*;
import javax.swing.*;

/**
* JSliderTest1
* @author John B. Matthews
*/
public class JSliderTest1 extends JPanel {

public static void main(String args[]) {
JFrame frame = new JFrame("Sliders!");
frame.setContentPane(new JSliderTest1());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(550, 325);
frame.setVisible(true);
}

public JSliderTest1() {
this.setLayout(new BorderLayout());
this.add(genVerticalSliderPanel(), BorderLayout.WEST);
this.add(genHorizontalSliderPanel(), BorderLayout.NORTH);
this.add(genHorizontalSliderPanel(), BorderLayout.CENTER);
this.add(genHorizontalSliderPanel(), BorderLayout.SOUTH);
this.add(genVerticalSliderPanel(), BorderLayout.EAST);
}

private JPanel genHorizontalSliderPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JSlider slider = new JSlider(JSlider.HORIZONTAL);
slider.setMaximumSize(new Dimension(400, Short.MAX_VALUE));
panel.add(Box.createVerticalGlue());
panel.add(slider);
panel.add(Box.createVerticalGlue());
return panel;
}

private JPanel genVerticalSliderPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
JSlider slider = new JSlider(JSlider.VERTICAL);
slider.setMaximumSize(new Dimension(Short.MAX_VALUE, 225));
panel.add(slider);
return panel;
}
}
 
K

Knute Johnson

Mark_Galeck said:
same problem, does not honor, heres the code foo.java , width is 200
not 400

import javax.swing.*;
import java.awt.*;

public class foo extends JApplet {
public void init() {
GridBagConstraints gridBagConstraints;

setLayout(new GridBagLayout());

gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.weightx = 1.0;
add(new JPanel(), gridBagConstraints);

gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
JSlider s = new JSlider(0, 400);
add(s, gridBagConstraints);
validate();
Dimension d = s.getSize();
d.width = 400;
s.setSize(d);
validate();
}
}

For some reason I'm having trouble reading your posts so I'll post a
reply to this one. See the code below for an example on how to create
your JSlider. Also, note that any time Swing GUI components are
accessed (and in particular created) it must be done on the event
dispatch thread (EDT). Your code in the init() method needs to be
called on the EDT just as the 'new test9()' below in my code is called.

BorderLayout will pay no attention to preferred sizes unless you pack
your container. But as soon as you resize the container, BorderLayout
changes the size of your components. GridbagLayout, unless you
specifically tell it to, won't. GBL doesn't honor maximum size though.

In my example below I set the minimum size too. If you make the frame
even a tiny bit smaller, GBL will resize the JSlider to minimum size.
No matter how big you make the frame though, it will stay preferred size.

One other note, the Dimension objects that you pass to the set?Size()
methods have to be different objects. You can't just reuse the same one
and change the width or height, as any changes will be made to the
original object and your sizes will be off. This is why I created a new
Dimension object for the minimum size.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test9 extends JFrame {
public test9() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JSlider s = new JSlider(0,400);
Dimension d = s.getPreferredSize();
d.width = 400;
s.setPreferredSize(d);
s.setMinimumSize(new Dimension(200,d.height));

add(s,c);

pack();
setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new test9();
}
});
}
}
 
M

Mark_Galeck

Thank you all for your replies, I really appreciate, but... none of
these suggestions work - any calls to setPreferredSize,
setMinimumSize, maximumSize, none of these have any effect, with most
layout managers, they just ignore them

the solution, I found out from an article written by some guru:

To set size of your component and still work with a layout manager:

write your own subclass , and override getPreferredSize, which is what
the layout manager calls.

(He chastises Sun for misleading and lack of documentation. )


Thank you again for your comments.
 
K

Knute Johnson

Mark_Galeck said:
Thank you all for your replies, I really appreciate, but... none of
these suggestions work - any calls to setPreferredSize,
setMinimumSize, maximumSize, none of these have any effect, with most
layout managers, they just ignore them

the solution, I found out from an article written by some guru:

To set size of your component and still work with a layout manager:

write your own subclass , and override getPreferredSize, which is what
the layout manager calls.

(He chastises Sun for misleading and lack of documentation. )


Thank you again for your comments.

I'll admit Sun's docs are not that good for telling you how things
really work. But setting preferred size works fine just as I showed you
in the example provided. Most of us stopped overriding
getPreferredSize() years ago because setting it works just fine and we
didn't need the extra code. Java is changing every day and while the
web has some great articles, check the date on them. If they are more
than a couple of years old there may well be new thought on the subject.

Usually problems with layoutmanagers come in two varieties, you have
selected the wrong layoutmanager or you are trying to control the exact
size of your component with a layoutmanager. Unending grief will attach
to both situations. The purpose of the layoutmanager is to help you
make things fit and to compensate for differences in font sizes, native
component sizes and multi-platform quirks. They work great if you let them.

I've converted the code to an applet for you, try it, I guarantee you it
will work. Try playing with the width argument in the <applet> tag. If
you set it to less than 400 the JSlider will be 200 pixels wide.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test9 extends JApplet {
public void init() {
EventQueue.invokeLater(new Runnable() {
public void run() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

JSlider s = new JSlider(0,400);
Dimension d = s.getPreferredSize();
d.width = 400;
s.setPreferredSize(d);
s.setMinimumSize(new Dimension(200,d.height));

add(s,c);
}
});
}
}

<html>
<head>
</head>
<body>
<applet code=test9.class width=450 height=200>
</applet>
</body>
</html>
 

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,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top