SWT GridLayout automatic column count - java

I'm using a SWT GridLayout for displaying different images in, such a wonder - a Grid.
Now my problem is, that the GridLayout has always a fixed column count, lets say 5.
Is there any way to make the GridLayout flexible, so that the column count increase or decrease depending on the size of the parent component? (E.g. when the window is resizied).
I could not find an option in the GridLayoutConstructor or the GridData. A RowLayout does not fill my needs

You can change the layout at runtime.
When your parent component's size changes, change its GridLayout's numColumns property and call layout(true) on the parent component.
final Shell shell = new Shell();
final GridLayout layout = new GridLayout( 3, true );
shell.setLayout( layout );
shell.addControlListener( new ControlAdapter() {
#Override
public void controlResized( ControlEvent event ) {
int newColumnNumber = 5; // Calculate your new value here.
layout.numColumns = newColumnNumber;
shell.layout( true );
}
} );

Related

Java SWT: setSize() not working on Button control

I have an ArrayList of buttons, and I'm trying to set all the buttons the same size of the last button.
This is my code:
ArrayList <Button> buttons = new ArrayList<Button>();
Composite numbersComposite = new Composite(composite, SWT.NONE);
numbersComposite.setLayout(new GridLayout(5, true));
for (int i=0; i<=49; i++) {
Button b = new Button(numbersComposite, SWT.TOGGLE);
b.setText(""+i);
buttons.add(b);
}
for (Button b : buttons) {
b.setSize(buttons.get(buttons.size()-1).getSize());
}
Something is wrong because not all the buttons have the same size. Is there any problem with setSize method on Buttons with TOGGLE style?
Edit
I see that buttons.get(buttons.size()-1).getSize() is giving a Point with 0,0 value. Why?
Edit 2
I tried with this code but nothing happens! not all of them have the same size. Why is this?
Point point = new Point(20, 20);
for (Button b : buttons) {
b.setSize(point);
}
You are mixing layouts with absolute positioning, which doesn't work.
setSize will only work when you are not using layouts.
If you are using layouts (which is usually the best choice) then you should set the appropriate layout data to the components you want to display.
Since you are using GridLayout for the parent Composite, its children should set GridData as layout data; for example this GridData will make the buttons use all the available space in the parent Composite:
for (int i = 0; i <= 49; i++) {
Button b = new Button(numbersComposite, SWT.TOGGLE);
// set the layout data
GridData buttonLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
b.setLayoutData(buttonLayoutData);
b.setText("" + i);
buttons.add(b);
}
Look to the constructors of GridData to see which other options you have.
Look here to know more about layouts in SWT: http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html

SWT- equal weights to GridLayout row elements?

I'm trying to add 7 Text widgets to a GridLayout row.
I want them all to be of the same width, but they come out funky:
//Columns
for(int i=0;i<7;i++) {
text = new Text(shell, SWT.BORDER);
text.setEditable(true);
data = new GridData(SWT.FILL, SWT.TOP,true,false,1,1);
text.setLayoutData(data);
cols.add(text);
}
Things I've tried:
Almost any combination of FILL/TOP and true/false to the GridData constructor (I was desperate).
Setting data.minimumWidth and data.widthHint to (window width)/7.
Yet the widgets are always in varying degrees of disarray.
You specify this on the GridLayout constructor, second parameter:
GridLayout layout = new GridLayout(7, true);
specifies 7 columns of equal width.
You can also use
layout.makeColumnsEqualWidth = true;

JDialog.pack() hides JLabel

I am trying to write a form in java, but after dynamically inserting JLabels to the current JDialog and doing a pack() the windows is resized to minimum. The JLabels are displayed, but I have to resize the window manually.
Here is the part where the JLabels are inserted:
public void displayQuizz(Test quiz){
int xLable = 44;
int yLable = 41;
int widthLable = 403;
int heightLable = 70;
int noOfQuestion = 1;
for(Question question : quiz.getQuestions()){
JLabel lblNewLabel = new JLabel(Integer.toString(noOfQuestion) + ". " + question.getStatement());
lblNewLabel.setBounds(xLable, yLable, widthLable, heightLable);
contentPanel.add(lblNewLabel);
contentPanel.revalidate();
contentPanel.repaint();
this.pack();
noOfQuestion++;
yLable += heightLable;
}
}
The pack() method sets the size of a Window (where JFrame and JDialog are subclasses from) to the preferred size.
The preferred size is determined by
The LayoutManager, which takes the arrangement of the components and
their preferred size into account
The component itself, if it does not have a layout manager
As you don't use a layout manager in your example (and set the bounds of the label manually), you also have to specify the preferred size yourself (see getPreferredSize(), the default is 0x0, that's the problem you encountered).
I'd encourage you to get used to always use layout managers (there's quite a lot of them, and you can easily write your own layout manager strategy if none suffices your needs).

Slider always has default width in table

I created a slider inside of a table like shown in the following code example as I know that the minimum width of the background is used for the slider width:
public OptionScreen(MainClass game) {
super(game);
preference = new PreferencesHelper();
font = this.getDefaultFont(25);
this.table = new Table();
if (Config.DEBUG)
this.table.debug();
// add volumenlabel
LabelStyle style = new LabelStyle(font, Color.WHITE);
volumenLabel = new Label(Config.VOLUMEN_LABLE, style);
table.add(volumenLabel).colspan(2);
table.row();
// add slider
Skin skin = new Skin();
skin.add("sliderbackground",
this.game.manager.get("data/sliderbackground.png"));
skin.add("sliderknob", this.game.manager.get("data/sliderknob.png"));
SliderStyle sliderStyle = new SliderStyle();
sliderStyle.background = skin.getDrawable("sliderbackground");
sliderStyle.background.setMinWidth(600f);
sliderStyle.knob = skin.getDrawable("sliderknob");
volumenSlider = new Slider(0f, 1f, 0.1f, false, sliderStyle);
volumenSlider.setValue(preference.getVolumen()); // load current volumen
volumenSlider.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
volumeValue.setText(String.format("%.01f",
volumenSlider.getValue()));
// sett the preference
preference.setVolumen(volumenSlider.getValue());
}
});
// add volslider to stage
table.add(volumenSlider);
volumenLabel.invalidate();
// table
style = new LabelStyle(font, Color.WHITE);
// set current volumen
volumeValue = new Label(
String.format("%.01f", volumenSlider.getValue()), style);
volumenLabel.setAlignment(2);
table.add(volumeValue).width(50f);
table.row();
initBackButton();
// init table
table.setPosition(Config.VIRTUAL_VIEW_WIDTH / 2,
Config.VIRTUAL_VIEW_HEIGHT / 2 - Config.BLOCK_SIZE * 10);
// add a nice fadeIn to the whole table :)
table.setColor(0, 0, 0, 0f);
table.addAction(Actions.fadeIn(2f)); // alpha fade
table.addAction(Actions.moveTo(Config.VIRTUAL_VIEW_WIDTH / 2,
Config.VIRTUAL_VIEW_HEIGHT / 2, 2f)); // move to center of the
// screen
// add to stage
this.stage.addActor(table);
}
The slide is inside a table with no width set. I already took a look if the width is set and if the calculation for the prefWidth of the slider does uses the set 600f.
Math.max(style.knob == null ? 0 : style.knob.getMinWidth(), style.background.getMinWidth())
Is the calculation for the width of the slider inside the Sliderclass. If I calculate that and log it, it loggs the desired 600f.
Everything seems right to me but the slider is rendered way to small for the 600 I set.
The background and knobtextures are 24x24.
So I hope you guys can tell me what I am doing wrong.
The folution is, that it's inside an table so the width is defined by the table width attibut for the spec. col and row.
So the fix is pretty short:
table.add(volumenSlider).width(600).height(60);
And its 600width and 60 height.
The wiki got edited to be more clear about this:
UI widgets do not set their own size and position. Instead, the parent widget sets the size and position of each child. Widgets provide a minimum, preferred, and maximum size that the parent can use as hints. Some parent widgets, such as Table, can be given constraints on how to size and position the children. To give a widget a specific size in a layout, the widget's minimum, preferred, and maximum size are left alone and size constraints are set in the parent.
Layout at Wiki
speedSlider.getStyle().knob.setMinHeight(100)

howto set the size of a Canvas, which doesn't have a layout

I am subclassing the Canvas in SWT, and calling pack() inside of the constructor,
the Canvas' size is computed as 64x64.
There is no Style or layout inside of my class.
How is the size computed at this here?
How can I change the size of my class? this.setSize() doesn't work.
public MyClass(Composite parent, int style) {
super(parent, SWT.NONE);
this.setBackground(getDisplay().getSystemColor(SWT.COLOR_YELLOW));
this.computeSize(1000, 1000, true);
this.pack();
Point s = this.getSize();
System.out.println(s.x); //prints 64
}
If you are subclassing Canvas then you can also override the computeSize method to force specific element sizes. This can be useful to make other elements flow around a fixed size component without having to use the layout hints, or if you want to make the canvas size set based on say an image that it's rendering.
This might be something like this in your MyCanvas class:
public Point computeSize (int widthHint, int heightHint, boolean changed) {
Point initialSize = super.computeSize (widthHint, heightHint, changed);
initialSize.x = 1000;
initialSize.y = 1000;
return initialSize;
}
You don't give yourself the size : it is given by the layout of the component using your MyClass.
So your canvas should be ready to handle any size.
Have you tried hinting the desided size via GridData?
final GridData data = new GridData();
data.widthHint = 1000;
data.heightHint = 1000;
canvas.setLayoutData(data);

Categories