How can we filter the table viewer in JFace based on the entered text - swt

I have created a table using table viewer and now i need to filter based on the text entered in the text box so how can we filter the table the code to create table is as follows
TableViewerColumn message = new TableViewerColumn(viewer, SWT.NONE);
message.getColumn().setWidth(800);
message.getColumn().setText("Message");
message.setLabelProvider(new ColumnLabelProvider()
{
#Override
public void update(ViewerCell cell)
{
Object element = cell.getElement();
if(element instanceof MyObject)
{
MyObject obj = (MyObject) element;
cell.setText(obj.getMessage());
}
}
});
}
private static class MyObject
{
private String first;
private String second;
private String message;
public MyObject(String first, String second,String message)
{
this.first = first;
this.second = second;
this.message = message;
}
public String getFirst()
{
return first;
}
public void setFirst(String first)
{
this.first = first;
}
public String getSecond()
{
return second;
}
public void setSecond(String message)
{
this.second = second;
}
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
so now how can we filter the table. Please help me as I am new to jface table viewer

Use a class derived from ViewerFilter to add a filter:
class MyFilter extends ViewerFilter
{
#Override
public boolean select(Viewer viewer, Object parentElement, Object element)
{
MyObject obj = (MyObject)element;
// TODO return true to include the object, false to exclude
}
}
Add this to the table with:
viewer.addFilter(new MyFilter());
Call
viewer.refresh();
to get the viewer to rerun the filter when the text changes.

Related

Is Realm's .where faster than filtering a list manually?

I am creating a project using a realm database.
I also have a lot of lists which I wish to filter while the user types.
The biggest one of them will probably be the list of customers
Currently I am using realm by using a wrapper class for each object (if anyone has a better suggestion I'm definitely open to it)
The objects I am using are like this:
public class Customer_Realm extends RealmObject{
private int _id;
private String _name; //...etc
public int get_id(){ return _id; }
public void set_id(int id) { _id = id;}
//etc
}
Public class Customer() {
Customer_Realm _base;
public Customer(Customer_Realm base) { _base = base;}
public int get_id(){ return _base.get_id(); }
public void set_id(int id) { _base.set_id(id);}
//...etc
}
Along with this I have an ArrayListAdapter for customer objects. My question is, would this:
public class CustomerAdapter extends ArrayListAdapter<Customer> {
List<Customer> _customers;
String _filter = null;
public void set_filter(string name) {
_filter = name;
notifyDataSetChanged();
}
#override
public int getCount(){
return get_visible().count();
}
public Customer getItem(int position){
return get_visible().get(position);
}
public List<Customer> get_visible() {
if (_filter == null)
return _customers;
List<Customer> visible = new ArrayList<Customer> ();
foreach (Customer c : _customers){
if (c.get_name().contains(_filter)
visible.add(c);
}
return visible;
}
}
Or would this be better?
public class CustomerAdapter extends ArrayListAdapter<Customer> {
Realm _database;
String _filter = null;
public void set_filter(string name) {
_filter = name;
notifyDataSetChanged();
}
#override
public int getCount(){
return get_visible().count();
}
public Customer getItem(int position){
return get_visible().get(position);
}
public List<Customer> get_visible() {
RealmResults<Customer_Realm> result = null;
if (_filter == null)
result = _database.allObjects(Customer_Realm.class);
else
result = _database.where(Customer_realm.class).contains("_name",_filter);
List<Customer> visible = new ArrayList<Customer> ();
foreach (Customer_Realm c : result){
visible.add(new Customer(c));
}
return visible;
}
}
Unfortunately my database contains only a small sample of data(and realm for windows does not have an editor so I can enter data manually) so when I try either implementation I do not see any difference, I was wondering if anyone has any experience with what happens when you use such an implementation with a large number of data
Thanks in advance for any help you can provide

TableViewer not refreshing in RAP

I tried to run my Eclipse RCP code to run in Eclipse RAP environment. In my Eclipse RCP code, there is functionality to add the rows in to table. But
adding the code does not work in Eclipse RAP. I am using TableViewer.
Following is my code.
public class BasicEntryPoint extends AbstractEntryPoint {
private static final int COLUMNS = 2;
private TableViewer viewer;
private class ViewContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object inputElement) {
List<Person> list = (List<Person>) inputElement;
return list.toArray();
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private class ViewLabelProvider extends LabelProvider implements
ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
Person p = (Person) element;
if (columnIndex == 0) {
return p.getName();
}
return p.getPlace();
}
}
private class Person{
String name;
String place;
public void setName(String name) {
this.name = name;
}
public void setPlace(String place) {
this.place = place;
}
public String getName() {
return name;
}
public String getPlace() {
return place;
}
}
public List<Person> persons() {
List<Person> list = new ArrayList<Person>();
Person person = new Person();
person.setName("bb");
person.setPlace("jjj");
list.add(person);
person = new Person();
person.setName("sss");
person.setPlace("fff");
list.add(person);
return list;
}
#Override
protected void createContents(Composite parent) {
parent.setLayout(new GridLayout(2, false));
viewer = new TableViewer(parent, SWT.NONE);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
final Table table = viewer.getTable();
viewer.setColumnProperties(initColumnProperties(table));
viewer.setInput(persons());
viewer.getTable().setHeaderVisible(true);
Button checkbox = new Button(parent, SWT.CHECK);
checkbox.setText("Hello");
Button button = new Button(parent, SWT.PUSH);
button.setText("World");
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Button clicked");
Person p = new Person();
p.setName("Dee");
p.setPlace("TCR");
persons().add(p);
String prop[] ={"name","place"};
viewer.update(p, prop);
//viewer.refresh();
}
});
}
private String[] initColumnProperties(Table table) {
String[] result = new String[COLUMNS];
for (int i = 0; i < COLUMNS; i++) {
TableColumn tableColumn = new TableColumn(table, SWT.NONE);
result[i] = "Column" + i;
tableColumn.setText(result[i]);
if (i == 2) {
tableColumn.setWidth(190);
} else {
tableColumn.setWidth(70);
}
}
return result;
}
}
You should use:
viewer.add(p);
rather than update to add a new item to a table (both for SWT and RAP).
You must also update your model to contain the new item.

GWT - celltable

I'm having problem with a column in my cell table not being populated with anything. Following is my code:
public class CellTableExample implements EntryPoint {
private static class Contact
{
private String address;
private String name;
private String phone="";
public Contact(String name, String address, String phone) {
super();
this.address = address;
this.name = name;
this.phone=getPhoneNumber(name);
}
}
public String getPhoneNumber(String name)
{
String pNum="";
SQLRunnerAsync service = (SQLRunnerAsync) GWT.create(SQLRunner.class);
AsyncCallback<String> callback = new AsyncCallback<String>()
{
#Override
public void onFailure(Throwable caught)
{
}
#Override
public void onSuccess(ArrayList<String[]> result)
{
pNum=reuslt;
}
};
service.findPhoneNum(name,callback);
return pNum;
}
// The list of data to display.
private static List<Contact> CONTACTS = Arrays.asList(
new Contact("John", "123 Fourth Road asdf asdf asdfasdf"),
new Contact("Mary", "222 Lancer Lane")
);
#Override
public void onModuleLoad() {
CellTable<Contact> table = new CellTable<Contact>();
SQLRunnerAsync service = (SQLRunnerAsync) GWT.create(SQLRunner.class);
AsyncCallback<ArrayList<String[]>> callback = new AsyncCallback<ArrayList<String[]>>()
{
#Override
public void onFailure(Throwable caught)
{
}
#Override
public void onSuccess(ArrayList<String[]> result)
{
compFlexTable.setPageSize(result.size());
Contact[] contactArr = new Contact[result.size()];
for(int i=0;i<result.size();i++)
{
String [] temp = result.get(i);
String name=temp[0];//name
String address=temp[1];//address
contactArr[i]=new Component1(name,address);
}
COMPONENT=Arrays.asList(compArray);
//address column
TextColumn<Contact> addressColumn = new TextColumn<Contact>(){
#Override
public String getValue(Contact contact) {
return contact.address;
}
};
//name column
TextColumn<Contact> nameColumn = new TextColumn<Contact>(){
#Override
public String getValue(Contact contact) {
return contact.name;
}
};
//name column
TextColumn<Contact> phoneColumn = new TextColumn<Contact>(){
#Override
public String getValue(Contact contact) {
return contact.phone;
}
};
service.getContactInfo(callback);
// Add the columns.
table.addColumn(nameColumn, "Name");
table.addColumn(addressColumn, "Address");
table.setRowCount(CONTACTS.size(), true);
table.setRowData(0, CONTACTS);
RootPanel.get().add(table);
}
}
So when I'm creating a contact object, another async method is being called to get the phone number for the contact. The table displays fine but the column for the phone number is empty. How do I resolve this? Any ideas/suggestions will be appreciated.. Thanks so much in advance.
You are misunderstanding the order of execution of your program. In getPhoneNumber, you set pNum to "", start an asynchronous request, and then return pNum. pNum is still "" at the end of this process. Later, when your asynchronous request returns, pNum is set to result, but at that point it's too late - your celltable has already been rendered.
Basically, you can't expect any asynchronous calls to complete in time to render your table accurately, once render has been called. All of the data you need must be immediately available before you render, or it won't show up. You can subclass a DataProvider to do these extra retrievals before asking the CellTable to render itself.
use asynchronous data provider as #Riley said
for more reference use the below link ..
http://www.mytechtip.com/2010/11/gwt-celltable-example-using_8168.html

Does anyone have a working examples of ActionCells working within a CompositeCell?

I tried following the example, http://gwt.google.com/samples/Showcase/Showcase.html#!CwCellTree , and added two ActionCells inside of the CompositeCell with no luck. The ActionCell's onBrowserEvent() does not get triggered.
This simple example works for me. Since you didn't provide any code or further explanation on what exactly you're trying to achieve, I have no idea whether my example is of any help or not.
public void onModuleLoad() {
CellTable<Person> table = new CellTable<Starter.Person>();
List<HasCell<Person, ?>> cells = new LinkedList<HasCell<Person, ?>>();
cells.add(new HasCellImpl("first name", new Delegate<Person>() {
#Override
public void execute(Person object) {
Window.alert(object.getFirstName());
}
}));
cells.add(new HasCellImpl("last name", new Delegate<Starter.Person>() {
#Override
public void execute(Person object) {
Window.alert(object.getLastName());
}
}));
CompositeCell<Person> cell = new CompositeCell<Person>(cells);
table.addColumn(new TextColumn<Starter.Person>() {
#Override
public String getValue(Person object) {
return object.getFirstName() + " " + object.getLastName();
}
}, "name");
table.addColumn(new Column<Person, Person>(cell) {
#Override
public Person getValue(Person object) {
return object;
}
}, "composite");
LinkedList<Person> data = new LinkedList<Starter.Person>();
data.add(new Person("Amy", "Reed"));
data.add(new Person("Tim", "Gardner"));
table.setRowData(data);
RootPanel.get().add(table);
}
private class HasCellImpl implements HasCell<Person, Person> {
private ActionCell<Person> fCell;
public HasCellImpl(String text, Delegate<Person> delegate) {
fCell = new ActionCell<Person>(text, delegate);
}
#Override
public Cell<Person> getCell() {
return fCell;
}
#Override
public FieldUpdater<Person, Person> getFieldUpdater() {
return null;
}
#Override
public Person getValue(Person object) {
return object;
}
}
private class Person {
private String fFirstName;
private String fLastName;
public Person(String first, String last) {
fFirstName = first;
fLastName = last;
}
public String getFirstName() {
return fFirstName;
}
public String getLastName() {
return fLastName;
}
}

how to add column of ClickableTextCells to cellTable

hi all
i need a simple example show me how to add column of ClickableTextCells to cellTable
thanks.
Column<YerValueObject, String> newCol = new Column<YerValueObject, String>(new ClickableTextCell()) {
#Override
public String getValue(YearValueObject obj) {
return obj.someMethod();
}
};
newCol.setFieldUpdater(new FieldUpdater<YerValueObject, String>() {
#Override
public void update(int index, YerValueObject obj, String value) {
//do whatever you need to here...
}
});
table.addColumn(newCol, "ClickColumn");
this is the solution if you need to add clickableTextCell to cellTable
// ClickableTextCell
ClickableTextCell anchorcolumn = new ClickableTextCell();
table.addColumn(addColumn(anchorcolumn, new GetValue<String>() {
public String getValue(Contact contact) {
return "Click " + contact.anchor;
}
}, new FieldUpdater<Contact, String>() {
public void update(int index, Contact object, String value) {
Window.alert("You clicked " + object.name);
}
}), "Anchor");
private <C> Column<Contact, C> addColumn(Cell<C> cell,final GetValue<C> getter,
FieldUpdater<Contact, C> fieldUpdater) {
Column<Contact, C> column = new Column<Contact, C>(cell) {
#Override
public C getValue(Contact object) {
return getter.getValue(object);
}
};
column.setFieldUpdater(fieldUpdater);
return column;
}
private static interface GetValue<C> {
C getValue(Contact contact);
}
// A simple data type that represents a contact.
private static class Contact {
private final String address;
private final String name;
private final String anchor;
public Contact(String name, String address, String anchor) {
this.name = name;
this.address = address;
this.anchor = anchor;
}
}
Create a Column overriding the onBrowserEvent method.
Like this:
new Column<T, String>(new TextCell()) {
#Override
public String getValue(T object) {
return object.getProperty();
}
#Override
public void onBrowserEvent(Context context, Element elem, T object, NativeEvent event) {
// TODO You can check which event you want to catch
Window.open("http://www.stackoverflow.com", "StackOverFlow", "");
}
};