In my TableViewer I have an OwnerDrawLabelProvider where for a specific column in my table I add a ProgressBar to a TableEditor instance.
My problem is the following:
I'm able to set the selection of the ProgressBar but when trying to update it remains at the same value.
CODE:
#Override
public void update(ViewerCell cell) {
if(columnIndex == 4){
Table table = tableViewer.getTable();
TableItem item;
TableItem[] items;
TableEditor editor;
items = table.getItems();
ProgressBar bar = new ProgressBar(table, SWT.NONE);
bar.setMinimum(0);
bar.setMaximum(100);
bar.setState(SWT.NORMAL);
bar.setSelection(0);
bar.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,true));
if(mediator.isSent()){
List<Item> itemsSendToSubmit = mediator.getItemsSendToSubmit();
if(!itemsSendToSubmit.isEmpty()){
for(Iterator<Item> itemIterator = itemsSendToSubmit.iterator(); itemIterator.hasNext(); )
{
Item itemSubmited = itemIterator.next();
for(TableItem tableItem: items)
{ if(tableItem.getText(0).contains(itemSubmited.getId()))
{
bar.setSelection(PluginUtility.getBuildProgress(itemSubmited.getPlan()));
editor = new TableEditor(table);
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor(bar, tableItem, 4);
}
}
}
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
I read about an issue that setSelection method for ProgressBar has some problems. I created my own ProgressBar by extending the base class and I overrided setSelection method with the fix code but still doesn't work.
In a normal main function, this works.
Can I get some suggestions of what can be the problem or how adding this ProgressBar in a TableViewer influences its behavior ?
EDIT: If I create a single instance of progressbar when the label provider is created and then pass it to the tableeditor it will update the progressbar for the last element on which I say editor.setEditor(bar, tableItem, 4);
but I need to display a progressbar for each item and update it for each item !
Perhaps the update happens, but the visuals are not updated, depending on how you call this code.
You have to make sure that you're not mobilizing the ui thread when you're doing this update.
In eclipse 3.x this means using
Display.getDefault().asyncExec(new Runnable() {
public void run() {
// ... do any work that updates the screen ...
}
});
Or using injection to get the UISynchronize in 4.x
Basically put the setSelection code in there.
See this article on background processing in eclipse plugins :
http://www.vogella.com/tutorials/EclipseJobs/article.html
When you update the value of ProgressBar, after that you need to redraw/repaint the TableViewer with all of its properties, then it will show the update progressbar. Hope this will solve your problem.
Related
I have a cell table showing some data. For each row, I want to have two columns which contain edit / delete buttons. When each button is clicked, it should be able to notify a listener which button was clicked (and preferably also be able to pass in the object that row is associated with).
How can I do this? Specifically, I know how to render a button, but how can I process the on-click event and pass in the object which the user clicked to edit or delete?
This is the standard approach:
myTable.addCellPreviewHandler(new Handler<MyObject>() {
#Override
public void onCellPreview(CellPreviewEvent<MyObject> event) {
if ("click".equals(event.getNativeEvent().getType())) {
if (event.getColumn() == 0 || event.getColumn() == 1) {
MyObject object = event.getValue();
Window.alert("Column clicked: " + event.getColumn());
}
}
}
});
This is a more efficient solution, because you only have one handler attached to a table, instead of trying to attach a handler to each button in each row.
I think you can make a foreach through all the rows in the celltable (I never worked with celltables)
And then you can add your own ClickHandler to the Button.
Something like that (not tested):
final int row = myrow; // add the row value or a object identifier or similar
Button delete_button = new Button("delete");
delete_button.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
// Insert your delete funciton
delete(row);
}
});
You mentioned a Listener, Listener are depreciated, use Handler instead.
I am using Vaadin 7.1.7.
I have a Table which has a few TextFields and a Button called "delete".
On click of the delete button, that particular row is to be deleted.
As i understand, I could remove table item as follows:
table.removeItem(itemID);
Unfortunately, I am unable to fetch the itemID of the row to remove it from the table.
Since, I used table.addItem(o, null); to addItems to it, how could I get the rowID/itemID on the click of the button inside buttonClickListener?
My trys so far have been:
#Override
public void buttonClick(ClickEvent event) {
Table t = (Table) event.getButton().getParent();
}
This has got me to the parent table but not to that particular item.
Thanks in advance
.
You could for example use setData(rowID) when you create the buttons.
The onClick you retrieve the associated data of the button and have the correct row id.
Provide a row id, override Button.ClickListener, and use the id in the click listener.
Object rowId = new Object();
Button button = new Button("Delete");
button.addClickListener(new RowDeleteListener(rowId));
//populate cells in the row, add the button & whatever
table.addItem(row, rowId);
public class RowDeleteListener implements Button.ClickListener {
Object rowId;
public RowDeleteListener(Object rowId) {
this.rowId = rowId;
}
public void buttonClick(ClickEvent event) {
table.removeItem(rowId);
}
}
Or André Schild’s solution, which is to use setData(rowId) on the button.
Button button = new Button("Delete");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
table.removeItem(getData());
}
});
//Populate row stuff.
button.setData(table.addItem(row, null));
I like the first solution slightly better because it's more obvious what's going on, and also because the button has the correct row id before it gets added to the table instead of after.
Or, if you feel like creating something obnoxious: you could use the Button object as the id for the row.
Button button = new Button("Delete");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
table.removeItem(this);
}
});
//populate row stuff, including adding the button to the row.
table.addItem(row, button);
I didn't test or compile any of these so... you know...
I need to update the store when the checkbox in the grid cell changed its state: to add or to remove the value from store. how to handle this event?
BTW, I create the checkbox in grid in this way:
column = new ColumnConfig();
column.setId("accepted");
column.setHeader("Accepted");
column.setWidth(55);
UPD2: Now I do the following:
create checkboxes as firstly decided:
CheckColumnConfig checkColumn = new CheckColumnConfig("accepted", "", 55);
CellEditor checkBoxEditor = new CellEditor(new CheckBox());
checkBoxEditor.setToolTip("If you click here server will consider this rule checking your messages");
checkColumn.setEditor(checkBoxEditor);
checkColumn.setHeader("apply");
configs.add(checkColumn);
than handle events in the grid like this:
UPD3:
grid.addListener(Events.CellMouseUp, new Listener<GridEvent>() {
#Override
public void handleEvent(GridEvent be) {
PropertyItem item;
if (grid.getStore().getAt(be.getRowIndex()).isAccepted()){
item = new PropertyItem(val1, val2, val3, true);
} else {
item = new PropertyItem(val1, val2, val3, false);
}
store.update(item);
store.commitChanges();
saveProperties(store, customerId, toRemove);
}
});
this is the right way.
According to the docs found here, you can add a listener to the CellEditor's Complete event. In the Complete event Listener, perform whatever activity you need to accomplish.
Update:
Try the following
column.setRenderer(new GridCellRenderer() {
#Override
public Object render(ModelData model, String property, ColumnData config, int rowIndex, int colIndex, final ListStore store, Grid grid) {
CheckBox box = new CheckBox();
box.addListener(Events.Change, new Listener<FieldEvent>() {
#Override
public void handleEvent(FieldEvent be) {
st.commitChanges();
saveProperties(st, customerId, toRemove);
// I'm not sure what saveProperties is, but see if this works now.
// this event should DEFINITELY be fired when the checkbox is clicked
// so if it doesn't work, try changing how you do your code here
// maybe by doing model.set(property, (Boolean) be.getValue()); or something
}
});
return box;
}
});
I use the TableViewer to show informations in a table. The user can select one of the shown options by selecting one line of the table.
I want to create a table in matrix form, in which the user can not only select the line. It should be possible to select every item of the table, like row 2 column 3. For every item selection an action is called to handle this item as it is in the TableViewer.
As far as i now, i can add CellModifier and CellEditors to the line of Columns of the table, but the reference for the action is always the line object and not the selected TableItem.
Does somebody have an example how to create such a matrix inside a Composite?
I can create it by setting a GridLayout and adding the components in a for-loop, but than i get issues, when i want to redraw the Composite with new childrens. The TableViewer does already have this handling, so i dont want to implement it again.
I had the same problem a while ago and the only way I found to solve it was to register a mouse listener on the SWT table widget associated to the table viewer.
MouseListener columnSelectionMouseListener = new ColumnSelectionMouseListener();
getViewer().getTable().addMouseListener(columnSelectionMouseListener);
public class ColumnSelectionMouseListener implements MouseListener {
private TableColumn selectedColumn;
#Override
public void mouseDoubleClick(MouseEvent e) {
// Nothing to do here
}
#Override
public void mouseDown(MouseEvent e) {
table = (Table) e.widget;
TableItem item = table.getItem(new Point(e.x, e.y));
for (int i = 0; i < table.getColumnCount(); i++) {
TableColumn column = table.getColumn(i);
Rectangle bounds = item.getBounds(i);
if (bounds.contains(e.x, e.y)) {
selectedColumn = column;
}
}
}
#Override
public void mouseUp(MouseEvent e) {
// Nothing to do here
}
public TableColumn getSelectedField() {
return selectedColumn;
}
}
Then, for example in the viewer's selection listener, you can ask to the mouse listener which column was selected when the mouse has been pressed and combine that with the selected line coming from the viewer's selection to perform the appropriate action.
Hope this can help.
Manu
Maybe the following JFace snippet will help:
Snippet058CellNavigationIn34
Ingo
I create a combo-box control in org.eclipse.swt.widgets.Table
The code snippet is below
...
TableEditor editor = new TableEditor (table_LLSimDataFileInfo);
CCombo combo = new CCombo (table_LLSimDataFileInfo, SWT.NONE);
combo.setText("CCombo");
combo.add("item 1");
combo.add("item 2");
editor.grabHorizontal = true;
editor.setEditor(combo, items[i], 0);
...
How can I dynamically change the combo-box list for a selected row in the table (For e.g. item1, item2 etc changed to item4, item5, item7 etc for row 5 only) by triggering of some event. The event in my case is selection in another combo-box whose list does not change
You should set a SelectionListener on your other CCombo, in order to call an update on your second CCombo.
This WavAudioSettingComposite class is a good example.
Something like:
public class ValueChanged extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
if(e.getSource()==myFirstCCombo){
// call update on your second CCombo
}
}
}
public void updateSecondCCombo(int[] newValues){
int oldbitrate=getFramerate();
mySecondCCombo.removeAll();
for (int i = 0; i < newValues.length; i++) {
mySecondCCombo.add(""+newValues[i]);
}
}
The TableEditor docs show a simple example with a selection listener that identifies the current selected row.
You just need to customize this example and dynamically fill the Combo acording to the selected row.