Editable SWT table - swt

How to edit SWT table Values without Using Mouse Listeners?

Do the TableEditor snippets in the below link help?
SWT Snippets
The first example in the TableEditor section uses a SelectionListener on the table (unlike the second example which uses a MouseDown event you mentioned you don't want)
You could perhaps make use of the TraverseListener or KeyListener too to help you achieve what you want.

final int EDITABLECOLUMN = 1;
tblProvisionInfo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
// Clean up any previous editor control
final TableEditor editor = new TableEditor(tblProvisionInfo);
// The editor must have the same size as the cell and must
// not be any smaller than 50 pixels.
editor.horizontalAlignment = SWT.LEFT;
editor.grabHorizontal = true;
editor.minimumWidth = 50;
Control oldEditor = editor.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// Identify the selected row
TableItem item = (TableItem) e.item;
if (item == null)
return;
// The control that will be the editor must be a child of the
// Table
Text newEditor = new Text(tblProvisionInfo, SWT.NONE);
newEditor.setText(item.getText(EDITABLECOLUMN));
newEditor.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent me) {
Text text = (Text) editor.getEditor();
editor.getItem()
.setText(EDITABLECOLUMN, text.getText());
}
});
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item, EDITABLECOLUMN);
}
});
Here tblProvision is the name of your table. you can just now edit Your table by clicking on it. I have Declare EDITABLECOLUMN. this is the column that u want to edit.

If you can use JFace as well and not just pain SWT, have a look at the JFace Snippets, especially
Snippet036FocusBorderCellHighlighter - Demonstrates keyboard navigation by highlighting the currently selected cell with a focus border showing once more the flexibility of the new cell navigation support
Snippet034CellEditorPerRowNewAPI - Demonstrates different CellEditor-Types in one COLUMN with 3.3-API of JFace-Viewers

You can get or set the value of a item, for example:
Table table = new Table(parent, SWT.NONE);
TableItem item = new TableItem(table, SWT.NONE);
item.setText("My new Text");

I suggest you to us TableViewer, it is very powerful table which it you can use databinding very easy too.

Related

How to add alternate colors to rows in Jface tableviewer

I am using a Jface table viewer with OwnerDrawLabelProvider for multiline rows, now I want to add alternate colors to the rows. I tried using colLabelProvider, but it is overwriting OwnerDrawLabelProvider. How do I achieve both?
Thanks in advance!
If you are using OwnerDrawLabelProvider you will have to do this in your provider. You can fill the cell background in the erase method using something like:
#Override
protected void erase(Event event, Object element)
{
Table table = (Table)event.widget;
TableItem item = (TableItem)event.item;
int row = table.indexOf(item);
Color color;
if ((row & 1) == 0)
color = event.gc.getDevice().getSystemColor(SWT.COLOR_GREEN);
else
color = event.gc.getDevice().getSystemColor(SWT.COLOR_RED);
event.gc.setBackground(color);
event.gc.fillRectangle(event.x, event.y, event.width, event.height);
}

Change value of widget inside GWT flex table when other widget's value changes?

Ok, so I have a pretty specific and to me quite complicated issue, as I'm a GWT newbie.
I have a GWT flex table, which I use to dynamically add rows, whose cells contain GWT widgets. The row number changes, but the number of columns in static, always 6. Each row contains a cell with a remove button and five cells each with their own textbox.
What I need to do is somehow code a kind of relationship between the textbox in cell 6 of one row and the textbox in cell 5 in the next row (and vice versa).
To illustrate: when something changes in the textbox at [1,6] the content of textbox at [2,5] needs to be overwritten with the same value. If the textbox at [2,5] changes the textbox at [1,6] needs to change as well. I cannot use a button to commit the changes, it needs to happen via onValueChange or Blur or something similar, which doesn't require the user to perform a specific action.
My problem stems mostly from trying to figure out how to address specific cells in the flex table and their content. For the remove button the solution was easy enough with a click event handler, but for this issue I just can't seem to be able to come up with a solution.
Sadly I also cannot provide any of the code which I have up until now, since it's a business secret. I can only give a broad description of the problem like the one above.
EDIT:
Actually, it's probably more a problem of not having much code in terms of this specific problem.
What I have is a flex table, which has initially only the header row. Upon clicking a button below this table the addNewField() method is called, which just contains the creation, setting of default values and adding of the text fields into a new row.
addNewField() {
int rows = flextable.getRowCount();
Button removeBtn = new Button("x");
removeBtn.getElement().setId(Integer.toString(rows));
//then the button's event handler
TextBox name = new TextBox();
name.setText("something");
flextable.setWidget(rows, 0, "name");
//repeat 4 more times with incrementing columns for the other widgets
}
This way I add entire rows of editable TextBoxes. What I need is a way to influence the values of the 6th column TextBox of a chosen row and the 5th column TextBox of chosen row + 1.
EDIT2: I've tried the dirty option just to see how it would go and somehow the compare inside the if breaks the app. The compiler detects a nullpointerexception and I can't even debug it with breakpoints because it fails to compile and won't start. I can't figure out why though. I threw the code directly into the event for testing purposes, so pardon the ugliness.
TextBox bis = new TextBox();
bis.setText(rows + ":10:00");
subs.setWidget(rows, 5, bis);
bis.addValueChangeHandler(new ValueChangeHandler<String>()
{
#Override
public void onValueChange(ValueChangeEvent<String> event)
{
allRows: for (int i = 0; i < subs.getRowCount(); i++)
{
for (int j = 0; j < subs.getCellCount(i); j++)
{
if ( subs.getWidget(i, j) == bis )
{
TextBox widgetAtColumnSix = ((TextBox) subs.getWidget(i, 5));
String text = widgetAtColumnSix.getText();
TextBox widgetAtColumnFiveRowPlusOne = ((TextBox) subs.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(text);
break allRows;
}
}
}
}
});
EDIT: Since you edited your question and you dont want to use EventBus you could iterate over your FlexTable and set your TextBox value depending on your current rowIndex and cellIndex... Its not nice but it should work:
public class CellWidget extends Composite {
private TextBox nameBox;
public CellWidget() {
FlowPanel flowPanel = new FlowPanel();
Button deleteButton = new Button("x");
nameBox = new TextBox();
nameBox.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
notifiyTextBox(CellWidget.this, event.getValue());
}
});
flowPanel.add(nameBox);
flowPanel.add(deleteButton);
initWidget(flowPanel);
}
public void setText(String text) {
nameBox.setText(text);
}
}
public void notifiyTextBox(CellWidget source, String string) {
rows: for (int i = 0; i < flextable.getRowCount(); i++) {
columns: for (int j = 0; j < flextable.getCellCount(i); j++) {
if (flextable.getWidget(i, j) == source) {
CellWidget widgetAtColumnSix = ((CellWidget) flextable.getWidget(i, 5));
widgetAtColumnSix.setText(string);
CellWidget widgetAtColumnFiveRowPlusOne = ((CellWidget) flextable.getWidget(i + 1, 4));
widgetAtColumnFiveRowPlusOne.setText(string);
break rows;
}
}
}
}
I still would recommend using an eventbus. To make it even more convenient there is the GWT Event Binder lib, which makes using events a breeze.
So when you change a value in your textbox[2,5] it also fires your CustomEvent. All Widgets, that need to change their textbox value just need to catch...

Can user add new Sections in a view?

I am using eclipse 3.6 and developing RCP application with java 6.
I am using the Section and trying to let the use able to add new n-sections. I need the text in the field after that.
Now the User can see a section. I need that he is able to add a n-sections and then to write text in stopRouteStreet-field. I would like to read all the n Text written in this field.
Any idea how to do this?.
Here is my code
Section sectionStop = toolkit.createSection(form.getBody(), Section.DESCRIPTION|Section.TWISTIE|Section.TITLE_BAR);
td = new TableWrapData(TableWrapData.FILL);
td.colspan = 2;
sectionStop.setLayoutData(td);
sectionStop.addExpansionListener(new ExpansionAdapter() {
public void expansionStateChanged(ExpansionEvent e) {
form.reflow(true);
}
});
sectionStop.setText(Messages.SearchMapView_endPoint); //$NON-NLS-1$
Composite sectionClientStop = toolkit.createComposite(sectionStop);
sectionClientStop.setLayout(new GridLayout());
final Composite stopComposite = toolkit.createComposite(sectionClientStop, SWT.NONE);
final GridLayout gridLayoutStop = new GridLayout();
gridLayoutStop.numColumns = 2;
stopComposite.setLayout(gridLayoutStop);
toolkit.createLabel(stopComposite, Messages.SearchMapView_Street);
stopRouteStreet = toolkit.createText(stopComposite, "", SWT.BORDER); //$NON-NLS-1$
sectionStop.setClient(sectionClientStop);
You need a global variable (a HashMap would do), that saves a mapping between each newly created Section and the Text control.
// define global field
HashMap <Section, Text> dynamicControls = new HashMap <Section, Text> ();
// after you create the text field, save the newly created Text field
....
...
dynamicControls.put(section, text);
// Later when you need to read the values in all the text fields
for(Section s: dynamicControls.keySet()){
Text textField = dynamicControls.get(s);
System.out.println(textField.getText());
}

Scrolling SWT Table programmatically

How to do vertical scroll of SWT table programatically?
I'm implementing search function on the table. When an item was found then it will be scrolled to the item found.
There are several methods you might want to try:
Table.showItem(TableItem)
Table.showSelection()
Table.showColumn(TableColumn)
Table.setTopIndex(int)
Other than that, I suggest using a TableViewer from JFace. Then you'd scroll to an item with this method:
TableViewer.reveal(Object)
My full time job is to develop SWT (on Linux), I hope to be able to provide a comprehensive answer:
From a SWT code point of view (at least on on GTK), there are only 3 Table functions that affect scrolling via an internal native call gtk_tree_view_scroll_to_*()
setTopIndex();
showSelection();
showColumn();
To explain what they do & how to use them:
Vertical Scrolling
This is done by setting focus or selecting a particular table item.
For Table:
setTopIndex(int) // Btw for Tree it's setTopItem(..)
showSelection() // which is also reached via setSelection().
setTopIndex(int) moves the view programatically to the desired position.
Below is a modified version of [Snippet52][1] that performs the desired job:
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell (display);
Table table = new Table (shell, SWT.BORDER | SWT.MULTI);
Rectangle clientArea = shell.getClientArea ();
table.setBounds (clientArea.x, clientArea.y, 200, 200);
for (int i=0; i<128; i++) {
TableItem item = new TableItem (table, SWT.NONE);
item.setText ("Item " + i);
}
table.setTopIndex(95); // <<<< This is the interesting line.
shell.pack ();
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
}
showSelection() on the other hand scrolls the view to the currently selected item. This method is also called by various setSelection(..) methods.
I.e setSelection(..) is typically used to scroll to the desired item and set keyboard focus on it. This is useful if you search for an item in a tree and would like user input (e.g 'enter') to act upon the item that you found. Snippet52 (mentioned above) performs this task.
Now it's worth noting that setSelection(..) doesn't trigger selectionListeners(...), so calling this method wouldn't invoke the associated action.
Horizontal Scrolling
This is done by focusing on a particular column via 'showColumn()'.
Below is a sample snippet that creates some rows & columns and then
scrolls to the last column.
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell (display);
Table table = new Table (shell, SWT.BORDER | SWT.MULTI);
table.setHeaderVisible (true);
Rectangle clientArea = shell.getClientArea ();
table.setBounds (clientArea.x, clientArea.y, 100, 100);
String[] titles = {"First", "Second", "Third", "Fourth", "Fifth"};
for (int i=0; i<titles.length; i++) {
TableColumn column = new TableColumn (table, SWT.NONE);
column.setText (titles [i]);
}
for (int i=0; i<128; i++) {
TableItem item = new TableItem (table, SWT.NONE);
item.setText (new String [] {"" + i, ""+i, ""+i, ""+i});
}
for (int i=0; i<titles.length; i++) {
table.getColumn (i).pack ();
}
shell.pack ();
shell.open ();
display.asyncExec(
// Sometimes table column sizes are computed later at runtime,
// to get around it, set the column index after initialization.
() -> table.showColumn(table.getColumn(4))
);
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
Note on Trees and Lists
Internally in SWT, Tree/Table/List all use the same native 'Tree' widget.
The above examples can be used for Lists and Tables as well, with the difference:
in Tree, setTopIndex(..) is setTopItem(..).
Lists don't have columns, so showColumn() is not applicable.
Let me know if you have further questions.
I don't really know what you need the search for, but you might also consider filtering the table to get to your desired element(kind of like a quick search).
Check it out:
http://eclipsesource.com/blogs/2012/10/26/filtering-tables-in-swtjface/
Hope it helps, cheers!

How can I make GWT list box editable a part from selection

As per my requirement I have written a custom panel which will display three ListBoxes to enable user to select date from this custom list boxes.These three list boxes are responsible for showing month,day,year value. Now I would like to make my three list boxes are editable and at the same time selectable. I mean I would like to provide a user preferences that date can editable and at the same time selectable. How can I do this in GWT. Here I am using GWT2.0. Any one please give an idea.
A browser does not provide such a control. Neither does GWT. You will need to code your own. EXT-GWT(not free) ComboBox has this functionality. http://www.extjs.com/examples/
So does Smart GWT (also not free) http://www.smartclient.com/smartgwt/showcase/#styled_combobox_category
If you were to roll your own, you would start with a Composite which has a TextBox and a VerticalPanel that is shown when a TextBox (or part of it) is clicked. Your panel would contain the clickable items.
You could work that out using a suggestBox instead of the list box. But user would have to start typing to display the list.
You can use absolute panel to achive the same ...
Below is the code snippet.
Hide the selectbox using textbox adjust the width and location of textbox so that it should cover dropdown list...
final AbsolutePanel absolute_panel_edit_list = new AbsolutePanel();
final TextBox onhold_textbox = new TextBox();
final ListBox onhold = new ListBox();
for (int onholdcount = 0; onholdcount < onHoldTypes.length; onholdcount++)
{
onhold.addItem(onHoldTypes[onholdcount]);
}
onhold.addKeyPressHandler(new KeyPressHandler()
{
#Override
public void onKeyPress(KeyPressEvent event)
{
onhold_textbox.setStyleName("onhold_textbox");
absolute_panel_edit_list.add(onhold,0,8);
absolute_panel_edit_list.add(onhold_textbox,1,10);
absolute_panel_edit_list.setSize("142px", "35px");
flex_row4.removeCell(4, 9);
flex_row4.setWidget(4, 9, absolute_panel_edit_list);
onhold_textbox.addMouseOutHandler(new MouseOutHandler()
{
#Override
public void onMouseOut(MouseOutEvent event)
{
String customized_time = onhold_textbox.getText();
int no_of_elements = onhold.getItemCount();
onhold.addItem(customized_time);
onhold.setSelectedIndex(no_of_elements);
flex_row4.removeCell(4, 9);
flex_row4.setWidget(4, 9, onhold);
flex_row4.setWidget(4, 11, completed_togglebutton);
flex_row4.setWidget(4, 13, completed_label);
}
});
}
});