I am creating an SWT application with two TreeViewers and a TableViewer in between them.
The TableViewer contains images in each row that indicate something about the date in that row of the TreeViewer.
However the problem is that the images in the TableViewer are not properly aligning with the rows in the TreeViewer. Is there any way for me to ensure that their rows stay exactly leveld?
Thanks
ADDED
You can change the way the height of a row is measured by overriding the behaviour of the "measuring method", i.e. adding a Listener to SWT.MeasureItem. There is a good example here. Just use the height of the icon you use in the TreeViewer plus maybe a couple of border pixels.
Here is the important code part:
Display display = new Display();
Shell shell = new Shell(display);
shell.setBounds(10,10,200,250);
final Table table = new Table(shell, SWT.NONE);
table.setBounds(10,10,150,200);
table.setLinesVisible(true);
for (int i = 0; i < 5; i++) {
new TableItem(table, SWT.NONE).setText("item " + i);
}
table.addListener(SWT.MeasureItem, new Listener() {
public void handleEvent(Event event) {
int clientWidth = table.getClientArea().width;
event.height = event.gc.getFontMetrics().getHeight() * 2;
event.width = clientWidth * 2;
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
Related
I am developing an application and my employer demands that it should have an absolute size (1024 x 768). Is it possible to insert this absolute composite into another composite with fill layout (or any other) and set the absolute layout to be always centralized?
I am fairly new to developing screens, so I'm confused with this concept.
Thanks in advance.
You can use GridLayout to center the Composite in the Shell.
Something like:
Display display = new Display();
Shell shell = new Shell(display, SWT.SHELL_TRIM);
shell.setText("Stack Overflow");
shell.setFullScreen(true);
shell.setLayout(new GridLayout());
// Composite, just using a border here to show where it is
Composite composite = new Composite(shell, SWT.BORDER);
// Center composite in the shell using all available space
composite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
composite.setLayout(new GridLayout());
// Something to put in the composite
Label label = new Label(composite, SWT.BEGINNING);
label.setText("Text");
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
I had an Eclipse plug-in app (ten-year-old code, no documentation, etc.) dropped in my lap and while adding new features to it, I noticed that when a panel is resized, the text boxes change size continuously while the separator is being dragged.
As you can see in the second picture, the text boxes are kind of randomly sized. Is there a setting in SWT that will prevent this from happening?
Here's how I'm creating one of the text boxes. The others are basically clones of this:
Font font = parent.getFont();
setLayout(new FillLayout());
SashForm sashForm = new SashForm(this, SWT.VERTICAL);
FormToolkit toolkit = new FormToolkit(getParent().getDisplay());
Section section = toolkit.createSection(sashForm,
Section.DESCRIPTION | ExpandableComposite.TITLE_BAR | ExpandableComposite.EXPANDED);
section.setLayoutData(new GridData(GridData.FILL_BOTH));
section.setLayout(new GridLayout());
section.setText("Section Title");
Composite controlComposite = toolkit.createComposite(section);
GridLayout controlLayout = new GridLayout();
controlLayout.numColumns = 2;
controlLayout.verticalSpacing = 20;
controlComposite.setLayout(controlLayout);
section.setClient(controlComposite);
Font bold = ResourceManager.getBoldFont(font);
Label textLabel = toolkit.createLabel(controlComposite, "Title:", SWT.BOLD);
GridData gd = new GridData();
gd.horizontalSpan = 1;
textLabel.setLayoutData(gd);
textLabel.setFont(bold);
textBox = new ExtendedText(controlComposite, SWT.BORDER | SWT.SINGLE, false);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 1;
gd.verticalSpan = 2;
textBox.setLayoutData(gd);
The ExtendedText class is an extension of StyledText. The important bits of it are this:
GridData gd_bg = new GridData(GridData.FILL_BOTH);
setLayoutData(gd_bg);
final GridLayout gridLayout = new GridLayout();
gridLayout.verticalSpacing = 0;
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.horizontalSpacing = 0;
gridLayout.numColumns = 1;
gridLayout.makeColumnsEqualWidth = true;
sashForm.setWeights(new int[] { 1, 1 });
Okay, after digging in a little deeper, I got it working as expected.
First, the controlComposite and controlLayout objects are now created using
Composite controlComposite = new Composite(section, SWT.NONE)
controlComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
controlComposite.setBackground(section.getBackground());
GridLayout controlLayout = new GridLayout(2, true);
controlLayout.marginHeight = 20;
controlLayout.marginWidth = 0;
controlLayout.verticalSpacing = 10;
controlLayout.horizontalSpacing = 0;
controlComposite.setLayout(controlLayout);
section.setClient(controlComposite);
Once I did that, things started to stabilize. I also ended up tweaking the weights to this:
sashForm.setWeights(new int[] { 2, 3 });
It's not perfect, but it'll do for now.
Thanks to #greg-449 and #Baz for taking a look
In an eclipse plugin, I try to show the user a dialog that just contains a long text. This text should be scrollable.
I tried:
protected Control createDialogArea(Composite parent)
{
Composite container = (Composite) super.createDialogArea(parent);
Text text = new Text(container, SWT.READ_ONLY | SWT.V_SCROLL | SWT.H_SCROLL| SWT.MULTI);
text.setText(" " + command + "\n\r\n\r" + result);
return container;
}
The text is then shown with a disabled scrollbar (although it is larger than the size of the window). How do I enable scrolling?
The issue seems to be, that your layoutdata on the text is not limited. So SWT appears to have no idea when to enable scrolling.
Setting griddata to fill both did not work for me with your code (just tried).
However, this will:
public static void main(String[] args) {
Display display = Display.getDefault();
Shell s = new Shell(display);
s.setSize(300, 300);
s.setLayout(new GridLayout(1, true));
Composite c = new Composite(s, SWT.NONE);
c.setLayout(new GridLayout(1, false));
Text text = new Text(c, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
GridData gridData = new GridData(SWT.NONE, SWT.NONE, false, false);
gridData.heightHint = 200;
gridData.widthHint = 200;
text.setLayoutData(gridData);
text.setBackground(s.getDisplay().getSystemColor(SWT.COLOR_WHITE));
text.setSize(250, 250);
Font stdFont = new Font(text.getDisplay(), new FontData("Consolas", 11, SWT.NORMAL));
text.setFont(stdFont);
StringBuffer buffer = new StringBuffer();
for (int row = 0; row < 40; row++) {
for (int column = 0; column < 20; column++) {
buffer.append("Word ");
}
buffer.append("\n");
}
text.setText(buffer.toString());
s.open();
while (!s.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
By restricting the size of your Text properly (with layoutdata, not setting the size), SWT now knows when the text is bigger than the area and enables scrolling.
Mind you, your solution does work, if you type something after creating (i know not possible for your case).
I works if you also set
text.setLayoutData(new GridData(GridData.FILL_BOTH));
I am using RowLayout for thumbnails of images. All the thumbnails are being displayed in one row only. How can I make them to display efficiently in multiple rows upon resizing?
You can easily find it in the documentation of RowLayout.
What you're looking for is RowLayout#wrap:
wrap specifies whether a control will be wrapped to the next row if there is insufficient space on the current row. The default value is true.
Since the default is true, it should already wrap...
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell();
shell.setText("StackOverflow");
RowLayout layout = new RowLayout();
layout.wrap = true;
shell.setLayout(layout);
Image image = new Image(display, "star.png");
for(int i = 0; i < 10; i++)
new Label(shell, SWT.NONE).setImage(image);
shell.pack();
shell.setSize(200, 100);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
image.dispose();
}
Looks like this before resizing:
And after resizing:
On a project based on eclipse RCP:
Using SWT and eclipse RCP I want to show error or info mark exactly the same as the following pictures. When the mouse pointer hovers the error mark, a popup shows the reason. I need this capability to show errors or warnings to the user.
It would be very nice to simultaneously have the same error in the problems view.
1) You need ControlDecorations (code taken from https://krishnanmohan.wordpress.com/2012/10/04/inline-validations-in-eclipse-rcp-field-assists/):
Label label = new Label(parent, SWT.NONE);
label.setText("Please Enter Pincode:");
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
Text txtPincode = new Text(parent, SWT.NONE);
txtPincode.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
//Adding the decorator
final ControlDecoration txtDecorator = new ControlDecoration(txtPincode, SWT.TOP|SWT.RIGHT);
FieldDecoration fieldDecoration = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry .DEC_ERROR);
Image img = fieldDecoration.getImage();
txtDecorator.setImage(img);
txtDecorator.setDescriptionText("Pls enter only numeric fields");
// hiding it initially
txtDecorator.hide();
txtPincode.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
Text text = (Text)e.getSource();
String string = text.getText();
char[] chars = new char[string.length()];
string.getChars(0, chars.length, chars, 0);
for (int i = 0; i < chars.length; i++) {
if (!('0' <= chars[i] && chars[i] <= '9')) {
txtDecorator.show();
} else {
txtDecorator.hide();
}
}
}
});
Obviously, you can use ModifyListener or VerifyListener instead of KeyListener. However, doing this manually for every field will result in a lot of unpleasant-to-maintain code. Surprisingly, SWT/JFace doesn't have a good built-in solution for validation, unless you are using data binding (as described in http://www.toedter.com/blog/?p=36). You could write your own small framework to simplify usage.
2) You need to use Markers, e.g.
IResource resource = ... // get your specific IResource
resource.createMarker(IMarker.PROBLEM);
marker.setAttribute(IMarker.MESSAGE, message);
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
Don't forget to remove the marker when the field is validated correctly.