I have two comboviewer and the idea is that the second combo will display a subset of options depending of the first combo value selected. But after to set the new input in the second combo and refresh the combo width is too small. How can I set it for auto adjusting to options width?
public class ExpresionDialog extends Dialog {
private ComboViewer combo1;
private ComboViewer combo2;
#Override
protected Control createDialogArea(Composite composite) {
Composite parent = (Composite) super.createDialogArea(composite);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1);
combo1 = new ComboViewer(parent);
combo1.setLabelProvider(new LabelProvider());
combo1.setContentProvider(ArrayContentProvider.getInstance());
combo1.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent e) {
IStructuredSelection sel = (IStructuredSelection) e.getSelection();
AttributeOption option = (AttributeOption) sel.getFirstElement();
combo2.setInput(getValuesCombo2(option));
combo2.refresh(true);
}
});
combo1.setInput(getValuesCombo1());
combo2 = new ComboViewer(parent);
combo2.setLabelProvider(new LabelProvider());
combo2.setContentProvider(ArrayContentProvider.getInstance());
return parent;
}
// Omitted getValuesCombo1 and getValuesCombo2 methods ...
}
You need to call the layout method of the parent Composite to get it to redo the child layouts each time you change the contents.
Related
I'm sadly far from being an expert in SWT and RCP, but I really tried my best here... I can't figure out how to configure the widgets to get this layout (just a Photoshopped screen, never worked this way):
This is what I get if I set the column number of the GridLayout to 2:
Here is the Refresh and the Blacklist button in the wrong row, but at least everything is visible...
And this is what I get if I set the column number of the GridLayout to 3:
This is total messed up... Most of the widgets are pushed outside the visible area. DatePicker, Refresh, Whitelist and the Calculate buttons are not visible, they are somewhere outside on the right.
This is the codepart for this screen area:
resultingProductsGroup = new Group(propProdGroup, SWT.NONE);
final GridData gd_resultingProductsGroup = new GridData(SWT.FILL,
SWT.CENTER, true, false);
gd_resultingProductsGroup.widthHint = 240;
resultingProductsGroup.setLayoutData(gd_resultingProductsGroup);
resultingProductsGroup.setText("Resulting products");
final GridLayout gridLayout_4 = new GridLayout();
gridLayout_4.numColumns = 2;
resultingProductsGroup.setLayout(gridLayout_4);
Label refDateLabel = new Label(resultingProductsGroup, SWT.NONE);
refDateLabel.setText("Reference date:");
refDateInput = new DateInput(resultingProductsGroup, SWT.BORDER);
refDateInput.setLayoutData(new GridData());
refDateInput.setValue(new Date());
calculateProductsButton1 = new Button(resultingProductsGroup, SWT.NONE);
setupImageButton(calculateProductsButton1, Images.getButtonRefresh());
calculateProductsButton1.setLayoutData(new GridData());
GridDataFactory.swtDefaults().hint(18, 18).applyTo(
calculateProductsButton1);
resultingProductsTable = new TableListWidget<Product>(
resultingProductsGroup, SWT.BORDER, ListWidgetMode.MULTI);
resultingProductsTable.setLinesVisible(true);
resultingProductsTable.setHeaderVisible(true);
final GridData rpTableProperty = new GridData(SWT.FILL, SWT.FILL, true,
true, 3, 1);
resultingProductsTable.setLayoutData(rpTableProperty);
GridDataFactory.swtDefaults().hint(230, 240).applyTo(
resultingProductsTable);
setupResultingProductsTableColumns();
resultingProductsTable.sortByComparator(new Comparator<Product>() {
#Override
public int compare(Product o1, Product o2) {
return o1.getPartNum().getExternalId().compareTo(
o2.getPartNum().getExternalId());
}
});
resultingProductsTable.addOpenListener(new IOpenListener() {
#Override
public void open(OpenEvent event) {
doResultingProductsTableOpen();
}
});
calculateProductsButton2 = new Button(resultingProductsGroup, SWT.NONE);
calculateProductsButton2.setText("Calculate");
whitelistAddButton = new Button(resultingProductsGroup, SWT.NONE);
whitelistAddButton.setText("Whitelist");
whitelistAddButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
doAddToWhitelist();
}
});
blacklistAddButton = new Button(resultingProductsGroup, SWT.NONE);
blacklistAddButton.setText("Blacklist");
blacklistAddButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
doAddToBlacklist();
}
});
What am I not seeing here? I'm stuck with this GUI bug for over 2 days now... Please, help me :)
You could design the whole composite with one GridLayout and 3 columns, while using horizontal span of 3 on the table. That doesn't give you the desired mocked up screen though, because reference date controls and buttons at the bottom would be aligned in columns.
Try instead using 3 composites
reference date: row layout
table: fill layout
button list: row layout
I am working on Eclipse plugin. Here i created a separate view and now i want to format the color of tree node.
These are code present in createpartcontrol method.
ScrolledComposite sc = new ScrolledComposite(parent, SWT.V_SCROLL );
Composite composite1 = new Composite(sc, SWT.NONE);
Composite composite_1 = creatingcomposite(composite1);
Tree tree = new Tree(composite_1, SWT.FULL_SELECTION );
TreeItem item = new TreeItem(tree, SWT.NONE);
here i want to set some colour like blue.
item.setText("This is sparta");
Now here i want some different colour like yellow on subsubitem text.
TreeItem subsubItem = new TreeItem(subItem, SWT.NONE);
subsubItem.setText(new String[] { "Function Name: "+ errorPreTest11.description.get(j).function });
For doing this i tried to set SWT.COLOR_BLUE but it's not working.
Use
item.setForeground(tree.getDisplay().getSystemColor(SWT.COLOR_BLUE));
You can also create your own colors but if you do this you must dispose of them when you are done.
I suggest you using the TreeViewer. In this case you would have a functionality to set a LabelProvier on your viewer. Label provider has a subclass called StyledCellLabelProvider, which you can successfully extend to provide styling of your labels like this: (Please also see a TextStyle class for more formating options).
public class MyStyledLabelProvider extends StyledCellLabelProvider {
private Styler defaultStyler;
public MyStyledLabelProvider () {
defaultStyler = new Styler() {
#Override
public void applyStyles(TextStyle textStyle) {
textStyle.strikeout = true;
}
};
}
#Override
public void update(ViewerCell cell) {
Object element = cell.getElement();
StyledString styledString = getStyledString(element);
cell.setText(styledString.toString());
cell.setStyleRanges(styledString.getStyleRanges());
super.update(cell);
}
#SuppressWarnings("unchecked")
private StyledString getStyledString(Object element) {
return new StyledString("Cell string", defaultStyler);
}
}
Is there a standard SWT control that resembles a button which displays an arrow and opens a dropdown menu when pressed and is not a toolbar-only control?
It would be something like this:
It is similar to a combo box control, except that the "button" area would act more similarly to an actual button - its text would not change based on your selection, it would appear depressed when clicked, and the items would be used for actions or navigational purposes instead of for selection. It's also similar to a control available for toolbars, but I need to use it on a regular composite instead.
This is nearly doable simply by using regular button and popup-menu controls - however, I do not believe I can display the arrow next to the text on the button this way. Anyway, since this kind of control seems fairly common, I assumed there would be a standard way to use these two things as one.
I think, this is what you should do get Drop down menu behavior
Create Menu with style SWT.DROP_DOWN
Create MenuItems on Menu
if you want a button
Create a Button with style SWT.ARROW | SWT.DOWN
add SelectionListener
In SelectionListener, Create a Menu with style SWT.POP_UP and position the menu at the button location.
//code
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setSize(300, 200);
shell.setText("Button Example");
shell.setLayout(new RowLayout());
/**
*
* Approach1
*
*/
final Composite btnCntrl = new Composite(shell, SWT.BORDER);
btnCntrl.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
btnCntrl.setBackgroundMode(SWT.INHERIT_FORCE);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).spacing(0, 1).applyTo(btnCntrl);
CLabel lbl = new CLabel(btnCntrl, SWT.NONE);
lbl.setText("Animals");
Button btn = new Button(btnCntrl, SWT.FLAT|SWT.ARROW|SWT.DOWN);
btn.setLayoutData(new GridData(GridData.FILL_VERTICAL));
btn.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem item1 = new MenuItem(menu, SWT.PUSH);
item1.setText("Hare");
MenuItem item2 = new MenuItem(menu, SWT.PUSH);
item2.setText("Fox");
MenuItem item3 = new MenuItem(menu, SWT.PUSH);
item3.setText("Pony");
Point loc = btnCntrl.getLocation();
Rectangle rect = btnCntrl.getBounds();
Point mLoc = new Point(loc.x-1, loc.y+rect.height);
menu.setLocation(shell.getDisplay().map(btnCntrl.getParent(), null, mLoc));
menu.setVisible(true);
}
});
/***
*
*
* Approach 2
*
*/
final Composite btnCntrl2 = new Composite(shell, SWT.BORDER);
btnCntrl2.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
btnCntrl2.setBackgroundMode(SWT.INHERIT_FORCE);
GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).spacing(0, 1).applyTo(btnCntrl2);
CLabel lbl2 = new CLabel(btnCntrl2, SWT.NONE);
lbl2.setText("Animals");
Button btn2 = new Button(btnCntrl2, SWT.FLAT|SWT.ARROW|SWT.DOWN);
btn2.setLayoutData(new GridData(GridData.FILL_VERTICAL));
btn2.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
super.widgetSelected(e);
Shell menu = (Shell) btnCntrl2.getData("subshell");
if(menu != null && !menu.isDisposed()){
menu.dispose();
}
menu = new Shell(shell, SWT.NONE);
menu.setLayout(new FillLayout());
Table table = new Table(menu, SWT.FULL_SELECTION);
table.addListener(SWT.MeasureItem, new Listener() {
#Override
public void handleEvent(Event event) {
event.height = 20; //TODO: determine later
}
});
table.addListener(SWT.PaintItem, new Listener() {
#Override
public void handleEvent(Event event) {
Rectangle bounds = event.getBounds();
event.gc.setBackground(event.display.getSystemColor(SWT.COLOR_BLUE));
event.gc.drawLine(bounds.x, bounds.y+bounds.height-1, bounds.x+bounds.width, bounds.y+bounds.height-1);
}
});
TableItem tableItem= new TableItem(table, SWT.NONE);
tableItem.setText(0, "Hare");
TableItem tableItem2= new TableItem(table, SWT.NONE);
tableItem2.setText(0, "Pony" );
TableItem tableItem3= new TableItem(table, SWT.NONE);
tableItem3.setText(0, "Dog");
Point loc = btnCntrl2.getLocation();
Rectangle rect = btnCntrl2.getBounds();
Point mLoc = new Point(loc.x, loc.y+rect.height);
menu.setLocation(shell.getDisplay().map(btnCntrl2.getParent(), null, mLoc));
menu.pack();
menu.setVisible(true);
btnCntrl2.setData("subshell", menu);
}
});
display.addFilter(SWT.MouseDown, new Listener() {
#Override
public void handleEvent(Event event) {
Shell shell = (Shell) btnCntrl2.getData("subshell");
if(shell != null && !shell.getBounds().contains(event.display.map((Control)event.widget, null, new Point(event.x, event.y)))){
shell.dispose();
btnCntrl2.setData("subshell", null);
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
This snippet shows how to use the described widget in a SWT toolbar. You can set the button text by using the item.setText() method.
This question is almost 10 years old, but just in case someone is still looking for a solution (like I just did ;) ):
I achieved a pretty close behaviour of your description using only a Button and a Menu using this approach: http://eclipseo.blogspot.com/2012/07/show-context-menu-programmatically.html
Button button = new Button(parent, SWT.PUSH);
button.setText("Animals");
Menu menu = new Menu(button);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("hare");
menu.addListener(SWT.Show, new Listener() {
#Override
public void handleEvent(Event event) {
menu.setVisible(true);
}
});
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
menu.notifyListeners(SWT.Show, null);
}
});
The result is that the menu is shown when you (left) click on the button.
Bonus: to achieve the expand icon at the end, you can add a unicode character for a down triangle in the button text like so:
button.setText("Animals \u2BC6");
HTH,
Ben
I want to use the JFace PopupDialog as lightweight dialog for user input. But I have some problems with the background color of text widgets.
As you can see below in 1, a SWT.MULTI text widget has no background and border, a SWT.SINGLE text widget has no background.
I tried to override the background color with:
Text comment = new Text(composite, SWT.MULTI|SWT.BORDER);
comment.setFocus();
comment.setBackground(new Color(Display.getDefault(), new RGB(000, 000, 000)));
// method of PopupDialog
applyBackgroundColor(new Color(Display.getDefault(), new RGB(000, 000, 000)), comment);
Does anybody has any idea how to handle this properly?
Thanks in advance!
EDIT: As requested, here is the source for the popup. I subclassed the PopupDialog, as I wanted the popup to be opened next to the Cursor location:
public class MouseLocationPopupDialog extends PopupDialog {
private final static int SHELL_STYLE = PopupDialog.INFOPOPUP_SHELLSTYLE;
public MouseLocationPopupDialog(Shell parent, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, null, infoText);
}
public MouseLocationPopupDialog(Shell parent, String titleText, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, titleText, infoText);
}
public MouseLocationPopupDialog(Shell parent, String infoText, final Point size) {
this(parent, infoText);
getShell().setSize(size);
}
public MouseLocationPopupDialog(Shell parent, int shellStyle, boolean takeFocusOnOpen, boolean persistSize, boolean persistLocation, boolean showDialogMenu, boolean showPersistActions, String titleText, String infoText) {
super(parent, shellStyle, takeFocusOnOpen, persistSize, persistLocation, showDialogMenu, showPersistActions, titleText, infoText);
}
#Override
protected void adjustBounds() {
super.adjustBounds();
Display d = Display.getCurrent();
if (d == null) {
d = Display.getDefault();
}
Point point = d.getCursorLocation();
getShell().setLocation(point.x + 9, point.y + 14);
}
}
The actual usage is as follows:
final PopupDialog dialog = new MouseLocationPopupDialog(HandlerUtil.getActiveShell(event), "Title", "Bottom bar") {
#Override
protected Control createDialogArea(Composite parent) {
Control composite = super.createDialogArea(parent);
Composite table = new Composite((Composite) composite, SWT.NONE);
table.setLayout(new GridLayout(2, true));
// text is a member variable
text = new Text(table, SWT.SINGLE | SWT.BORDER);
Button submit = new Button(table, SWT.PUSH);
return composite;
}
#Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
final Color backgroundColor = new Color(Display.getCurrent(), new RGB(255, 255, 255));
text.setBackground(backgroundColor);
final Color foregroundColor = new Color(Display.getCurrent(), new RGB(0,0,0));
text.setForeground(foregroundColor);
backgroundColor.dispose();
foregroundColor.dispose();
return contents;
}
};
dialog.open();
Note that this Popup is independent from other UI elements: The code will not wait for the completion of the popups open() like other JFace dialogs (e.g. TitleAreaDialog)
First of all, use SWT.BORDER instead of SWT.BORDER_SOLID. If you're lucky, this somehow causes your problem. Other than that, from your small snippet alone it's hard to see what goes wrong. Unless there is some other code that resets the background color later on, this should work.
Update:
Try to override the method getBackground() of PopupDialog and let it return the color you want. Your code probably is in createDialogArea(..) and PopupDialog applies this color to basically everything after your code.
If you only want to change the background color of specific controls, you could try the following:
#Override
protected Control createContents(Composite parent) {
Composite contents = super.createContents(parent);
// set the color here
return contents;
}
I have a composite element, that initially has a Label. Now I call dispose on the it (the label) and create another label in the same container (composite elm), but I don't see the new text. It brings me to question how do I enable redraw on the composite, so that the new label (or any other component I might create) will render in place of the old one.
Here is the code I have (separated into a unit test for redraw a composite)
private Label createLabel( Composite parent) {
Label label = new Label(parent, SWT.NONE);
label.setAlignment(SWT.CENTER);
label.setLayoutData( new GridData( SWT.CENTER, SWT.CENTER, true, true) );
return label;
}
private void changeText() {
assert testCell != null : "Please initialize test cell";
testCell.getChildren()[0].dispose();
Label l = createLabel(testCell);
l.setText("New TexT");
testCell.redraw();
}
private void draw() {
Display display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout(2,false));
testCell = new Composite(shell,SWT.BORDER);
testCell.setLayout(new GridLayout());
Label l = createLabel(testCell);
l.setText("Old Text");
Composite btnCell = new Composite(shell,SWT.NONE);
btnCell.setLayout(new GridLayout());
Button b = new Button(btnCell, SWT.PUSH);
b.setText("Change");
b.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event e) {
changeText();
}
});
As you can see, I am calling redraw on the composite after I add a new element. Also, I have verified that after the call to dispose, testCell.getChildren().length returns 0, as expected, and when I create a new label, I get the same expression to return 1, verifying that the new element is indeed getting added to its parent composite container
Am I missing something here ?
In the changeText() function, the
testCell.redraw();
line should be replaced by
testCell.layout();
Or, if you want to resize it correctly you should use
shell.layout();.
I would say add a selectionListener on the label.
.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
//Change text by Label.setText();
}
}