Is there anyway to pouplate table row after clicking Tree Item.?I don't want to use SWT/Jface TreeTableViewer. Suppose i have Tree with some tree items like cosmetics, Powder. When i click on cosmetic, related value should be populated in table.
Here is a small example:
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, true));
final Tree tree = new Tree(shell, SWT.SINGLE);
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
/* initialize columns */
TreeItem cosmetics = new TreeItem(tree, SWT.NONE);
cosmetics.setText(0, "cosmetics");
/* other text */
TreeItem powder= new TreeItem(tree, SWT.NONE);
powder.setText(0, "powder");
/* other text */
/* add selection listener to add children */
tree.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
/* get selection */
TreeItem[] items = tree.getSelection();
if(items.length > 0)
{
String parent = items[0].getText();
System.out.println(parent);
/* add new child */
TreeItem newItem = new TreeItem(items[0], SWT.NONE);
newItem.setText(0, "new Item, parent: " + parent);
/* Expand parent */
items[0].setExpanded(true);
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
It will add a new child to every TreeItem you click on.
i have got the solution
TreeViewer treeViewer= new TreeViewer(comp);
final TableViewer viewer= new TableViewer(comp1, SWT.BORDER);
treeViewer.addSelectionChangedListener(new ISelectionChangedListener()
{
public void selectionChanged(SelectionChangedEvent event)
{
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
Object obj= selection.getFirstElement();
viewer.setInput(obj);
}
});
}
Related
I am building a SWT application and have a menu created. Menu has multiple menu items like Add, Edit, Help. On click of each Menu Item, I want to show a composite which will display the details of it. I am able to build it, problem I am facing is, the space of hidden composite is not taken by visible composite. How can we make the composite occupy the entire space.
Also I am adding the selection listener to make the current composite visible and other composite hidden. In the current app there will multiple menu items and each one will have composite associated it. Listener needs reference of all composites to make them visible/hidden. Is there any better approach to do this.
public class MenuToggle {
boolean startup = true;
Menu menu, fileMenu, helpMenu;
Composite composite1,composite2;
public MenuToggle(Shell shell) {
createMenu(shell);
createFileView(shell);
createHelpView(shell);
startup = false;
}
public void createMenu(Shell shell) {
//Menu Bar
menu = new Menu(shell, SWT.BAR);
//File Menu
fileMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem fileMenuHeader = new MenuItem(menu, SWT.CASCADE);
fileMenuHeader.setText("&File");
fileMenuHeader.setMenu(fileMenu);
MenuItem fileSaveItem = new MenuItem(fileMenu, SWT.PUSH);
fileSaveItem.setText("&Save");
MenuItem fileExitItem = new MenuItem(fileMenu, SWT.PUSH);
fileExitItem.setText("E&xit");
//Help Menu
helpMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem helpMenuHeader = new MenuItem(menu, SWT.CASCADE);
helpMenuHeader.setText("&Help");
helpMenuHeader.setMenu(helpMenu);
MenuItem helpGetHelpItem = new MenuItem(helpMenu, SWT.PUSH);
helpGetHelpItem.setText("&Get Help");
shell.setMenuBar(menu);
fileSaveItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
composite1.setVisible(true);
((GridData)composite1.getLayoutData()).exclude = false;
composite2.setVisible(false);
((GridData)composite2.getLayoutData()).exclude = true;
composite2.layout(true, true);
}
});
helpGetHelpItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
composite1.setVisible(false);
((GridData)composite1.getLayoutData()).exclude = true;
composite2.setVisible(true);
((GridData)composite2.getLayoutData()).exclude = false;
composite2.layout(true, true);
}
});
}
public void createFileView(Shell shell) {
composite1 = new Composite(shell, SWT.BORDER);
composite1.setVisible(true);
GridData gd1 = new GridData(SWT.FILL, SWT.FILL, true, true);
composite1.setLayoutData(gd1);
composite1.setLayout(new GridLayout(1,true));
Label label = new Label(composite1, SWT.CENTER);
label.setBounds(composite1.getClientArea());
label.setText("Saved");
}
public void createHelpView(Shell shell) {
composite2 = new Composite(shell, SWT.BORDER);
composite2.setVisible(false);
GridData gd2 = new GridData(SWT.FILL, SWT.FILL, true, true);
composite2.setLayoutData(gd2);
composite2.setLayout(new GridLayout(1,true));
Label label1 = new Label(composite2, SWT.CENTER);
label1.setBounds(composite2.getClientArea());
label1.setText("No worries!");
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
shell.setText("Menu Display");
MenuToggle instance = new MenuToggle(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
There are a number of issues here.
You are using FillLayout for the Shell layout, so the GridData you are setting on the composites is ignored. You must use GridLayout for the Shell:
public static void main(final String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout()); // Changed
When you change the exclude settings you must call layout on the parent of the composite - the shell:
fileSaveItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
composite1.setVisible(true);
((GridData)composite1.getLayoutData()).exclude = false;
composite2.setVisible(false);
((GridData)composite2.getLayoutData()).exclude = true;
shell.layout(true, true); // change
}
});
helpGetHelpItem.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
composite1.setVisible(false);
((GridData)composite1.getLayoutData()).exclude = true;
composite2.setVisible(true);
((GridData)composite2.getLayoutData()).exclude = false;
shell.layout(true, true); // change
}
});
You are calling setBounds on the Label controls, this does not work when you are using layouts because the layout also calls setBounds and overrides your settings, use setLayoutData instead
Label label = new Label(composite1, SWT.CENTER);
label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // replace
//label.setBounds(composite1.getClientArea()); // wrong
As for dealing with lots of Composite controls you could call shell.getChildren and loop through the child controls. Or add the composites to a List and loop through that.
How to do a discrete (row-by-row) scrolling in SWT Table (JFace TableViewer)?
I need a Table to be scrolled "one unbroken row at a time", putting a full cell on top.
I use JFace TableViewer, but I didn't find a way to add a mouse-listener to it, so I made something like this:
TableViewer table = new TableViewer(shell, SWT.BORDER_DASH |SWT.FULL_SELECTION);
//some visual settings ommited here
table.getControl().addMouseWheelListener(new MouseWheelListener() {
#Override
public void mouseScrolled(MouseEvent e) {
Table sourceControl = (Table)e.getSource();
System.out.println(e.count);
if(e.count >=0)
sourceControl.setTopIndex(sourceControl.getTopIndex()-1);
else
sourceControl.setTopIndex(sourceControl.getTopIndex()+1);
}
});
But it turned out, that first of all if e.count equals to 3 or more, some rows are being missed. Secondly sometimes setTopIndex() not placing rows correctly.
Can it be done in more accurate way?
From what I can tell, adding a e.doit = false in the Listener works perfectly. Here is an example:
public static void main(String[] args)
{
final Display display = new Display();
Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
final Table table = new Table(shell, SWT.NONE);
for (int i = 0; i < 100; i++)
{
TableItem item = new TableItem(table, SWT.NONE);
item.setText("Item " + i);
}
table.addListener(SWT.MouseWheel, new Listener()
{
#Override
public void handleEvent(Event e)
{
e.doit = false;
if (e.count >= 0)
table.setTopIndex(table.getTopIndex() - 1);
else
table.setTopIndex(table.getTopIndex() + 1);
}
});
shell.pack();
shell.setSize(shell.getSize().x, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
The only case where the TableItem at the top isn't displayed completely is when you reach the end of the Table and the table's height isn't an exact multiple of the TableItem's height.
When I press a button, I want to change the foreground color of the selected item in a List.
So far, I tried this:
list.setForeground(display.getSystemColor(SWT.COLOR_RED));
but it changes the foreground color of all the items, not just the selected one.
Any ideas how to solve this?
Doing this with a List would require custom drawing. You are better off using a Table instead (or even a TableViewer depending on your requirements). Here is an example of a table that does what you want:
public static void main(String[] args)
{
final Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, false));
shell.setText("StackOverflow");
final Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
for (int i = 0; i < 10; i++)
{
TableItem item = new TableItem(table, SWT.NONE);
item.setText("item " + i);
}
Button button = new Button(shell, SWT.PUSH);
button.setText("Color selected");
button.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
List<TableItem> allItems = new ArrayList<>(Arrays.asList(table.getItems()));
TableItem[] selItems = table.getSelection();
for (TableItem item : selItems)
{
item.setForeground(display.getSystemColor(SWT.COLOR_RED));
allItems.remove(item);
}
for (TableItem item : allItems)
{
item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
Before button press:
After button press:
Just a note: This is not the most efficient way to do it, but should give you the basic idea.
List does not supports what you want.
Use Table and Table items instead.
Each table item represent a row, and it has setForeground(Color) method.
Here is my full coding.I have Two class firstone MyDateTime and Second one is Employee.
i have included currently working coding of mine.For the EmployeePart class,AbstractEditorPart is our own parent class Which is extended
public class MyDateTime extends DateTime{
public DateTime(Composite parent, int style)
{
super(parent, style);
}
public Date getValue()
{
Date date = new Date(getYear(), getMonth(), getDay());
return date;
}
}
public Class EmployeePart extends AbstractEditorPart(
private MyDateTime currentDate;
public void createBody(Composite parent){
currentDate=Util.createDateChooserCombo(parent, toolkit, "Date:", 2);
}
public void save(Employee input){
return null;
}
}
}
Turns out to be a little more complicated than I first thought.
One solution is to define a TabList for the Composite that contains your Widgets.
This way you can first define in which order you want them to be traversed.
Then add a Listener to each of the Widgets you want to traverse. This Listener will determine the next item in the TabList and force the focus on this item when either Tab or Enter is pressed.
Here is some example code:
public static void main(String[] args)
{
Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Composite content = new Composite(shell, SWT.NONE);
content.setLayout(new FillLayout());
Text first = new Text(content, SWT.BORDER);
Text second = new Text(content, SWT.BORDER);
content.setTabList(new Control[] {first, second});
Listener enterListener = new Listener()
{
#Override
public void handleEvent(Event event)
{
/* Is it a traverse via Tab or Enter? */
if(event.keyCode == SWT.CR || event.keyCode == SWT.TRAVERSE_RETURN || event.keyCode == SWT.TRAVERSE_TAB_NEXT)
{
/* Get source of event */
Widget source = event.widget;
/* Get traverse order of content composite */
Control[] tabList = content.getTabList();
/* Try to find current position in the tab list */
for(int i = 0; i < tabList.length; i++)
{
if(source.equals(tabList[i]))
{
/* Get the next item in the tab list */
Control nextControl = tabList[(i + 1) % tabList.length];
/* And force the focus on this item */
nextControl.setFocus();
nextControl.forceFocus();
return;
}
}
}
}
};
first.addListener(SWT.KeyUp, enterListener);
second.addListener(SWT.KeyUp, enterListener);
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
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