SWT - computingSize for Multi-line textfield inside ScrolledComposite - java

I have a composite(innerComposite) within a ScrolledComposite(sc). At runtime, additional UI components can be added. So I'm using the code below to set the minimum size of the sc to enable scrolling, in case that the additional UI components "overflow" the sc.
sc.setMinSize(
innerComposite.computeSize(
innerComposite.getSize().x, SWT.DEFAULT
)
);
One issue is with the SWT Multi-Line textfield inside this sc/innerComposite.
textBox = new org.eclipse.swt.widgets.Text(parent, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
When I enter a long text into this multi-line textfield, the vertical scrollbar will appear, (which is what I wanted!). However, when I call the code above to recompute the size and setting the sc.setMinSize()...the multi-line textfield's height will expand to fit the length of the text entered. This is not what I wanted. I want this height to remain on with the scrollbar and not resize to fit the text entered.
I know computeSize will cast its children to resize to the preferred size. I don't want this to happen to the multiline textfield as it has the capability of scrolling the vertical bar.
How can I prevent this from happening?

An alternative way of solving your problem is writing your own custom layout and setting that to your inner composite. This way you can control exactly how the controls will appear.

The solution is to use GridLayout in the content Composite. This allows you to set a GridData as layoutData on the text which contains both a wHint+hHint (which is used when doing computeSize() on the composite ) but still activate verticalGrab which will attribute any additional space to this composite.
In other words: the preferred size of the GridLayouted Composite uses the hHint/wHint from the GridData's of its children. This allows you to set the preferred size of you Text while still expanding the text using GridData.verticalGrab if extra space is available.

i solved this by setting the width/height!

Related

Table resizing and occupy the space left by vertical scrollbar

I want the table to resize and occupy the space left by vertical scrollbar when I delete the rows.
This is the table with vertical scrollbar:
And when I delete the rows, then I get this the table without vertical scrollbar:
.
I tried using
natTable natTable = new NatTable(panel, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.DOUBLE_BUFFERED | SWT.V_SCROLL);
and was working fine but the horizontal scrollbar was not coming even after I tried to set it from the viewportlayer.
First, of course with that code the horizontal scrollbar is not coming, you did not set the style bit to include a horizontal scrollbar. You should leave the default style bits in place and let NatTable do the necessary actions.
Second, you are not providing enough information on your setup. Are you using percentage sized columns? What are you triggering to delete a row? Is it a custom command or the NatTable default command?
What I know is that there is an issue with percentage sizing and setting the scrollbar invisible because that does not trigger a resize on the Composite. Feel free to create a ticket so I can have a look at this.

How to prevent resizing of a SWT combo?

When I call setItems(String[]) the combo box will become wider to fit the length of the new items.
How to make it not resizable no matter how wide the new items are?
I've tried it with ControlListener. I saved the initial size of the combo and set it each time the controlResized() was called. As the result the combo width remains constant but the rest of the UI looks ugly when I resize it. It is a wizard. I'm using GridLayout
If you are using GridLayout for your layout you can specify a widthHint in the layout data for the combo.
GridData data = new GridData(....);
data.widthHint = 100;
combo.setLayoutData(data);
If this is in a dialog you can use convertWidthInCharsToPixels(chars) to specify a width in characters rather than pixel. Dialog also has a static version of this method you can use outside of a dialog.

How to get a Label with wrapped text?

I ave tried the following code:
Label label = new Label(reallyLongString, skin);
label.setWrap(true);
label.setWidth(100); // or even as low as 10
table.add(label);
...
and yet all I get is a very wide line that draws off the screen. How to get a Label with wrapped text?
This is the same issue as seen in slider always has default width or "Slider always has default width".
You need to put that label into a table and add the right size to the cell of the table where the label is.
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.
Source: From the libgdx wiki Scene2D
The solution:
Label label = new Label(reallyLongString, skin);
label.setWrap(true);
label.setWidth(100); // or even as low as 10
table.add(label).width(10f);// <--- here you define the width
I've found that the following code can solve the issue without any table or wrapping container (for libgdx-1.9.6):
label = new Label("Some label", skin);
label.setPosition(600, 50);
label.setWidth(200);
label.setHeight(50);
label.setWrap(true);
stage.addActor(label);
If you just want to specify the preferred size for a single widget, wrap it with a Container.
https://github.com/libgdx/libgdx/wiki/Scene2d.ui#layout-widgets
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Container.html
Something like:
Container<Label> labelContainer = new Container(myLabel);
labelContainer.prefWidth(200.0f);
Keep in mind that the actual size will vary depending on the container hierarchy - for example, the labelContainer above will display differently if placed in another layout object.
The size will also vary depending on the viewport, etc.

Auto-Resizing JTextArea

I want my JTextArea to resize itself (expand vertically) when the last line (that the text area's height can offer) is reached and the user wants to start a new line. You know, like the textbox in MSWord.
I have an idea to use getLineCount() and determine (if necessary) the new height of the JTextArea. Do you have, or know of better approaches for implementing this?
Actually, the JTextArea always has the correct size so all lines of text are visible. What you experience is probably that you wrapped the text area in a JScrollPane. Just omit the scroll pane and make the text area a direct child of the container.
Another solution is to listen to resize events of the text area and size the scroll pane accordingly. This way, you can grow to a certain size and then start to display scroll bars (for example, when someone pastes 500KB of text into the text area).
I had the same problem. From my tests, I do not believe that the JTextArea sets its size dynamically. Instead, its size seems to be limited by its container (a JPanel in my case). However, the JTextArea does change its preferred size based on the text it contains. From the documentation:
java.awt.TextArea has two properties rows and columns that are used to determine the preferred size. JTextArea uses these properties to indicate the preferred size of the viewport when placed inside a JScrollPane to match the functionality provided by java.awt.TextArea. JTextArea has a preferred size of what is needed to display all of the text, so that it functions properly inside of a JScrollPane. If the value for rows or columns is equal to zero, the preferred size along that axis is used for the viewport preferred size along the same axis.
Go to JTextArea "Properties" - checklist "lineWrap".
I had the same problem,I put the JTextArea into a JScrollPane and set the preferred size of JTextArea, and I believe that's the cause of the problem.
So the right solution is to put the JTextArea into a JScrollPane, and don't touch the preferred size of JTextArea, set JScrollPane's instead.

Can a layout manager spawn several JPanels?

I have to build a rather large form with many controls. The controls are divided in basic controls/settings and extended controls/settings. The user can decide if he wants to see only the basic or both basic and extended controls.
I've dropped all extended controls onto their own JPanel so that I can easily switch between the two views by showing or hiding this panel.
Currently I'm using GroupLayout and what happens is that the controls on different panels are not aligned:
Label aaa: Text field
Label a: Text field
Label aaaaaa: Text field
----------------------------
Label b: Text field
Label bbb: Text field
Label bb: Text field
Unfortunatly I found now way to "synchronize" the layouts of the two panels (except using AbsoluteLayout and fixed control coordinates)
Is there any way to achive this?
Is my whole design flawed?
EDIT: If it is possible I would like to keep the GroupLayout manager.
As far as I know, no Swing LayoutManager (from JRE or open source) can span several panels.
I am currently working on such a feature (which I called "layouts synchronization") for my DesignGridLayout project, but it is not something easy to implements (I have started about 2 weeks ago and I still don't see exactly if and when I will get to something interesting, but I still have high hope for it;-))
One option you could check would be to add all components to the same panel (with just one GroupLayout then) and hide/show them based on user's selection. Hopefully, GroupLayout will adapt the size to the situation (after calling pack()).
If GroupLayout behaves well, then it would just be a matter of calling pack() each time after user changes his selection to show/hide extended fields.
Else you would have to manually set the size of your panel every time the user changes his selection.
Probably the easiest (good) way to do it is to add all the components to the main panel. Set the subpanels to non-opaque, and add the also to the main panel. The main panel the needs optimised drawing to be switched off.
Another technique is to add a spacer component. To the bottom panel add a component in the same column as the labels which dynamically takes the width component of its various size methods from the top labels. Do the same in reverse to the top panel.
I think there is no way to do it with the standard layout managers. You'll probably have to write your own layout manager, but it shouldn't be too hard if you subclass GroupLayout.
You could use GridLayout instead of GroupLayout which will give you uniform spacing between the columns
If you want to keep them in separate panels with separate layouts:
Iterate over all of the labels that you add, and find the maximum preferred width of each.
Iterate a second time, and set the preferred size to that each label's preferred height, but the maximum width.
This is the explanation of th GridLayout. This will set every component to the size, you expect it. With the GridData object you can specify how the components are ordere.
Examples
(source: sun.com)

Categories