How To Implement Custom Tree Columns and Cells In Eclipse RCP - java

I need to implement custom columns in Eclipse RCP for tree component. Columns like Combo or a selection button that can display another selection dialog. By default, Eclipse tree columns only support raw text strings. I want to replace the simple TextBox (or label) with another control. How can I achieve that?
The following example implements a simple text cells.
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Table table = new Table(shell, SWT.BORDER);
table.setHeaderVisible(true);
table.setLinesVisible(true);
for (int i = 0; i < 2; i++) {
new TableColumn(table, SWT.NONE);
}
table.getColumn(0).setText ("Task");
table.getColumn(1).setText ("Progress");
for (int i = 0; i < 40; i++) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText("Task " + i);
}
table.getColumn(0).pack();
table.getColumn(1).setWidth(128);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();

If you want to put Controls there, it's probably not because you can only display text (which itself isn't exactly true), it's because you want the contents to be editable. So use cell editors1. You can written tutorials at https://eclipse.org/articles/Article-Table-viewer/table_viewer.html
and http://www.java2s.com/Tutorial/Java/0280__SWT/TableCellEditorComboTextandButton.htm .

Related

ScrolledCompsite in TabFolder sizes content to zero

I have the following problem:
I'm using SWT to create a GUI for my application. I have a TabFolder in which I add several TabItems and in each of those I create a ScrolledComposite that holds some content.
The TabFolder is displaying fine, however the ScrolledComposite in the TabFolder does only show it's content in the first TabItem. All other ScrolledComposites are visible themselves just fine but their content is invisible.
Here is a little code snippet that demonstrates what I am referring to:
Display display = new Display();
Shell topShell = new Shell(display);
topShell.setSize(800, 800);
topShell.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
topShell.setLayout(new FillLayout());
TabFolder folder = new TabFolder(topShell, SWT.NONE);
for (int i = 0; i < 5; i++) {
TabItem item = new TabItem(folder, SWT.NONE);
item.setText("Item " + i);
ScrolledComposite scroller = new ScrolledComposite(folder,
SWT.H_SCROLL | SWT.V_SCROLL );
scroller.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
Composite content = new Composite(scroller, SWT.NONE);
content.setBackground(display.getSystemColor(SWT.COLOR_RED));
scroller.setContent(content);
scroller.setExpandHorizontal(true);
scroller.setExpandVertical(true);
item.setControl(scroller);
}
topShell.setVisible(true);
while (!topShell.isDisposed()) {
display.readAndDispatch();
}
You can tell that the content is being displayed if the area is painted red. If the content is invisible the area is blue (the background of the ScrolledComposite)
I'm not sure if that matters but this occurs on Linux Mint 18 and it appears to only happen within GTK 3 (in 2 it works just fine)
After quite some time I tracked the issue down to the following:
It turned out that the problem was that the "missing" content had a size of zero, because the layouting doesn't set the size of those.
In my case it could be fixed by removing the SWT.V_SCROLL and the SWT.H_SCROLL style constants from the ScrolledComposite. Therefore the above code written as following works as expected.
Display display = new Display();
Shell topShell = new Shell(display);
topShell.setSize(800, 800);
topShell.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
topShell.setLayout(new FillLayout());
TabFolder folder = new TabFolder(topShell, SWT.NONE);
for (int i = 0; i < 5; i++) {
TabItem item = new TabItem(folder, SWT.NONE);
item.setText("Item " + i);
ScrolledComposite scroller = new ScrolledComposite(folder,
SWT.NONE);
scroller.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
Composite content = new Composite(scroller, SWT.NONE);
content.setBackground(display.getSystemColor(SWT.COLOR_RED));
scroller.setContent(content);
scroller.setExpandHorizontal(true);
scroller.setExpandVertical(true);
item.setControl(scroller);
}
topShell.setVisible(true);
while (!topShell.isDisposed()) {
display.readAndDispatch();
}
Although that causes all content to be properly sized it completely removes the ScrollBars of the ScrolledComposite which somehow is not what you want from a ScrolledComposite.
Does anyone know how to fix that or whether that is a bug (that might have been fixed in newer SWT versions)?
I've fixed bugs related to this a few months ago.
Can you try latest SWT master?
http://download.eclipse.org/eclipse/downloads/

Resize toolbar SWT

I am trying to set the height of ToolBar to match other items in the grid layout. Here is the code I am using:
public TestSwt() {
Display display = new Display();
shell = new Shell(display, SWT.SHELL_TRIM);
shell.setSize(800, 800);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 1;
shell.setLayout(gridLayout);
Composite composite = new Composite(shell, SWT.NONE);
composite.setSize(100, 100);
GridLayout childGridlayout = new GridLayout();
childGridlayout.numColumns = 10;
composite.setLayout(childGridlayout);
composite.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
final Link link = new Link(composite, SWT.NULL);
link.setText("Link1");
Link link1 = new Link(composite, SWT.NULL);
link1.setText("Link2");
ToolBar toolBar = new ToolBar(composite, SWT.BORDER | SWT.VERTICAL);
ToolItem item = new ToolItem(toolBar, SWT.PUSH);
item.setText("toolbar");
// Trying to resize toolbar
Point size = toolBar.computeSize(SWT.DEFAULT, link.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
toolBar.setSize(size);
toolBar.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
The output I get is:
The output I want is:
I am sure I am missing something very basic. Any help will be really appreciated.
Edit:
As Andrew suggested I set the GridData as LayoutData. It did resize the toolBar but the text is not visible.
Using the code:
GridData toolBarlayout = new GridData(SWT.LEFT, SWT.TOP, true, true);
toolBarlayout.heightHint = link.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
ToolBar toolBar = new ToolBar(composite, SWT.BORDER | SWT.VERTICAL);
toolBar.setLayoutData(toolBarlayout);
ToolItem item = new ToolItem(toolBar, SWT.PUSH|SWT.TOP);
item.setText("toolbar");
The output is something like:
The GridLayout will allow the link widgets to grow to the height of the row, and will size the height of the row to accommodate the toolbar, and the toolbar wants to be at least as big as it is in your output. For that reason, you might have to explicitly set the height you want for the ToolBar (in pixels) rather than taking it from the Link. But you can put some logging in to see what computeSize() is actually returning.
I would create a GridData for the ToolBar, set the heightHint on the GridData to the height you want, and call toolBar.setLayoutData.
GridData toolBarLayoutData = new GridData();
toolBarLayoutData.heightHint = ...;
toolBar.setLayoutData(toolBaryLayoutData);

Place the label in the top SWT

I have two labels placed in the gridLayout. label 1 is just one word and the label 2 is 4 lines.
Since the label 2 is 4 lines, label 1 is verticaly centered, but I want that to be vertically in the top.
Below is the label settings I have used.
Label label = new Label(parent, SWT.WRAP);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING, GridData.VERTICAL_ALIGN_BEGINNING, false, false);
gd.widthHint = 200;
label.setLayoutData(gd);
Kindly help me in placing the label alignment on top not in the center for label 1
If you look at the Javadoc of GridData.HORIZONTAL_ALIGN_BEGINNING and GridData.VERTICAL_ALIGN_BEGINNING, you can see that it says:
Not recommended. Use new GridData(SWT.BEGINNING, int, boolean, boolean) instead.
and
Not recommended. Use new GridData(int, SWT.BEGINNING, boolean, boolean) instead.
Always use the SWT alignment constants:
public static void main(String[] args)
{
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(2, false));
Label left = new Label(shell, SWT.BORDER);
left.setText("LEFT");
Label right = new Label(shell, SWT.BORDER);
right.setText("RIGHT\nRIGHT\nRIGHT\nRIGHT");
GridData data = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
left.setLayoutData(data);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
right.setLayoutData(data);
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
Looks like this:

Set ScrollableComposite position to location

Using the SWT ScrollableComposite, is there an easy way in which to set the scrollbar position to jump in such a way that a particular element will be positioned at the top?
For example, if I had such a composite filled with 26 labels going down with the letters of the alphabet in order:
...then, say that I want to set my view to the "J" label and have the scrollbar position set like this:
(This is only example - if I really wanted to do what I am describing here, I would clearly just use a listbox or a table for my letters instead.)
This is similar to how Internet Browsers work when jumping to a specific tag within a page.
This can likely be done with a bunch of manual measurement calculations, if necessary, but my hope is that something simpler exists.
I believe you are looking for below method on ScrolledComposite
org.eclipse.swt.custom.ScrolledComposite.showControl(Control) //make it visible in view port
org.eclipse.swt.custom.ScrolledComposite.setOrigin(Point) //sets left corner coordinates, read SWT docs
Updated Answer:
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Map<String,Control> controlMap = new HashMap<String,Control>();
final ScrolledComposite scrollComposite = new ScrolledComposite(shell,
SWT.V_SCROLL | SWT.BORDER);
final Composite parent = new Composite(scrollComposite, SWT.NONE);
for (int i = 0; i <= 50; i++) {
Label label = new Label(parent, SWT.NONE);
String index = String.valueOf(i);
controlMap.put(index, label);
label.setText(index);
}
GridLayoutFactory.fillDefaults().numColumns(1).applyTo(parent);
scrollComposite.setContent(parent);
scrollComposite.setExpandVertical(true);
scrollComposite.setExpandHorizontal(true);
scrollComposite.addControlListener(new ControlAdapter() {
public void controlResized(ControlEvent e) {
Rectangle r = scrollComposite.getClientArea();
scrollComposite.setMinSize(parent.computeSize(r.width,
SWT.DEFAULT));
}
});
shell.open();
Control showCntrl = controlMap.get(String.valueOf(5));
if(showCntrl != null){
scrollComposite.setOrigin(showCntrl.getLocation());
}
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}

java SWT: how can I draw a widget to an offscreen buffer

I would like to draw the contents of a StyledText widget in to an Image; this will then provide a convenient way to stick the image into a Table cell.
Any suggestions about the best way to go about this?
Why do you want to create an image?
You could just render the the StyledText-widget in the table cell. If you have a lot of items and it is a performance problem you could create a virtual table by using SWT.VIRTUAL. If you're using JFace check out org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider.
If you're using plain SWT you should be able to use a TableEditor with a StyledText-widget as the editor. Something like this:
Table table = new Table(new Shell(new Display()), SWT.NONE);
table.setHeaderVisible (true);
TableColumn column = new TableColumn (table, SWT.NONE);
StyledText styledText = new StyledText(table, SWT.NONE);
TableItem item = new TableItem (table, SWT.NONE);
TableEditor editor = new TableEditor (table);
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor (styledText, item, 0);

Categories