Eclipse JFace/SWT ViewerFilter select never gets called - eclipse

I'm trying to build a simple dialog with a TableViewer in it, along with a checkbox which would filter the data. However the table is empty and the filtering never gets done. Whats wrong with this code?
public class AsTestDialog extends TitleAreaDialog {
private Table table;
private AsTestFilter filter;
private TableViewer tableViewer;
public AsTestDialog(Shell parentShell) {
super(parentShell);
}
#Override
public void create() {
super.create();
setTitle("Table Test");
}
#Override
protected Control createDialogArea(Composite parent) {
Composite area = (Composite) super.createDialogArea(parent);
area.setLayout(new GridLayout(1, false));
tableViewer = new TableViewer(area, SWT.BORDER | SWT.FULL_SELECTION);
table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tblclmnNewColumn = tableViewerColumn.getColumn();
tblclmnNewColumn.setWidth(130);
tblclmnNewColumn.setText("Column1");
TableViewerColumn tableViewerColumn_2 = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tblclmnId = tableViewerColumn_2.getColumn();
tblclmnId.setWidth(150);
tblclmnId.setText("Column2");
Composite composite = new Composite(area, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
Button btnFilter = new Button(composite, SWT.CHECK);
btnFilter.setBounds(10, 10, 111, 20);
btnFilter.setText("Filter");
btnFilter.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("CHECKBOX SELECTED");
filter.setFilterType("foobar");
tableViewer.refresh();
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {}
});
addTestData(table);
//Filter
filter = new AsTestFilter();
tableViewer.addFilter(filter);
tableViewer.getTable().pack();
tableViewer.refresh();
return area;
}
private void addTestData(Table table) {
TableItem item1 = new TableItem(table, SWT.NONE);
item1.setText(new String[] {"1","2"});
item1.setData("1");
TableItem item2 = new TableItem(table, SWT.NONE);
item2.setText(new String[] {"3","4"});
item2.setData("3");
}
}
The filter class:
public class AsTestFilter extends ViewerFilter {
private String filterType = "all";
public void setFilterType(String tp) {
this.filterType = tp;
}
#Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
System.out.println("SELECT CALLED: "+filterType);
return true;
}
}

If you are using the JFace TableViewer you must use a 'content provider' set with
tableViewer.setContentProvider(provider);
and then call
tableViewer.setInput(input data);
creating TableItem objects directly will not work properly as TableViewer expects to create these objects itself.
If you have a simple array or List of objects the content provider can simply be:
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
and the set input:
tableViewer.setInput(array or list);
Your filter is not called because you have not called setInput, the table viewer does nothing until this is called.

The ViewerFilter operates on the TableViewer's input, which will be null in your case as you aren't using tableViewer.setInput(model). Instead you are creating TableItems directly.
You will need to set up a content provider, label provider, and define a model which you can pass to .setInput for the table viewer, and remove the function which directly creates the TableItems.
Once you do this, the ViewerFilter should work.
There are plenty of tutorials around which describe this, including https://eclipse.org/articles/Article-Table-viewer/table_viewer.html and http://wiki.eclipse.org/index.php/JFaceSnippets

Related

Part of Text cut(hidden) in JFace ComboBoxCellEditor

I have an issue with jface ComboBoxCellEditor that part of the text is cut like the image below.
I'm using these plugins,
org.eclipse.swt_3.106.1.v20170926-0519.jar org.eclipse.swt.win32.win32.x86_64_3.106.1.v20170926-0519.jar org.eclipse.jface_3.13.1.v20170810-0135.jar
This issue only happens on Windows, not on UBUNTU, so it seems to be a bug of SWT or jface. I filed a bug report against Eclipse SWT 533282, but haven't got a response yet. If any of you know about this issue and there's a workaround for this, that will be greatly useful for me.
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
class CyTableComboBug extends Dialog
{
int mComboIndex;
String[] mComboItems = new String[] { "Combo Item 1 long string",
"Combo Item 2" };
public CyTableComboBug(Shell parentShell)
{
super(parentShell);
}
#Override
protected Control createDialogArea(final Composite parent)
{
final Composite container =
(Composite) super.createDialogArea(parent);
TableViewer viewer = new TableViewer(container,
SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL |
SWT.FULL_SELECTION | SWT.BORDER);
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText("Column 1");
column.setLabelProvider(new Column1LabelProvider());
column.setEditingSupport(new Column1EditingSupport(viewer));
viewer.setContentProvider(new ArrayContentProvider());
viewer.setInput(new Integer[] { 0 });
column.getColumn().pack();
Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
return container;
}
private class Column1LabelProvider extends ColumnLabelProvider
{
#Override
public String getText(Object element)
{
return mComboItems[mComboIndex];
}
}
class Column1EditingSupport extends EditingSupport
{
protected ComboBoxCellEditor mEditor;
public Column1EditingSupport(TableViewer viewer)
{
super(viewer);
mEditor = new ComboBoxCellEditor(
viewer.getTable(), mComboItems,
SWT.READ_ONLY | SWT.BORDER);
mEditor.setActivationStyle(
ComboBoxCellEditor.DROP_DOWN_ON_MOUSE_ACTIVATION);
}
#Override
protected boolean canEdit(final Object element)
{
return true;
}
#Override
protected CellEditor getCellEditor(final Object element)
{
return mEditor;
}
#Override
protected Object getValue(final Object element)
{
return mComboIndex;
}
#Override
protected void setValue(final Object element, final Object value)
{
mComboIndex = (int) value;
}
}
}

How to replace a button and re position it dynamically?

I have a text box and a add button next to it, when I click on add button I am able to add a text box and delete button next to it. Now I want the add button on the first row to be changed to delete and the add button should be re-positioned below two rows, when the second row delete button is clicked (the second row is deleted )the add button should go back to the first row and replace delete button. It should look like following.
How do I achieve this?
If you create a Composite as a container of sorts, you can add and remove from it allowing everything outside to remain in the correct order. By reserving the space, the delete button is always below the contents of the container.
I have a text box and a add button next to it, when I click on add button I am able to add a text box and delete button next to it
For example, if we have a small Shell with an add Button as you mentioned, and an empty space to add the Text widgets to:
final Composite baseComposite = new Composite(shell, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
baseComposite.setLayout(new GridLayout());
final Composite rowsContainerComposite = new Composite(baseComposite, SWT.BORDER);
rowsContainerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
rowsContainerComposite.setLayout(new GridLayout());
final Button addButton = new Button(baseComposite, SWT.PUSH);
addButton.setText("Add");
(For now the empty space is grabbing all available space, but you can change that as needed)
When adding rows, you can add to the rowsContainerComposite:
addButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
new Row(rowsContainerComposite);
rowsContainerComposite.layout();
}
});
A sample Row class:
public class Row {
final Composite baseComposite;
public Row(final Composite parent) {
baseComposite = new Composite(parent, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
baseComposite.setLayout(new GridLayout(2, false));
final Text text = new Text(baseComposite, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Button deleteButton = new Button(baseComposite, SWT.PUSH);
deleteButton.setText("Delete");
deleteButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
baseComposite.dispose();
parent.layout();
}
});
}
}
when the second row delete button is clicked (the second row is deleted )the add button should go back to the first row
Then when deleted, rows will shift back appropriately:
the add button should be re-positioned below two rows
The idea is that by using the "container" composite, you're reserving that space to add and remove the rows from. The delete button will always be below the rows as they are added and removed.
Full example:
public class AddDeleteButtonTest {
private static class Row {
final Composite baseComposite;
public Row(final Composite parent) {
baseComposite = new Composite(parent, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
baseComposite.setLayout(new GridLayout(2, false));
final Text text = new Text(baseComposite, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Button deleteButton = new Button(baseComposite, SWT.PUSH);
deleteButton.setText("Delete");
deleteButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
baseComposite.dispose();
parent.layout();
}
});
}
}
private final Display display;
private final Shell shell;
public AddDeleteButtonTest() {
display = new Display();
shell = new Shell(display);
shell.setLayout(new FillLayout());
final Composite baseComposite = new Composite(shell, SWT.BORDER);
baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
baseComposite.setLayout(new GridLayout());
final Composite rowsContainerComposite = new Composite(baseComposite, SWT.BORDER);
rowsContainerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
rowsContainerComposite.setLayout(new GridLayout());
final Button addButton = new Button(baseComposite, SWT.PUSH);
addButton.setText("Add");
addButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
new Row(rowsContainerComposite);
rowsContainerComposite.layout();
}
});
}
public void run() {
shell.setSize(200, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void main(final String... args) {
new AddDeleteButtonTest().run();
}
}
I did the same in one of my project. The code is bit complicated to do in Jface/SWT. Adding and removing widgets on composite will be bit heavy task. This will reduce UI performance.
If you use Jface tableviewer instead of creating composite, you will get better UI performance and good look as well. In table viewer in one column you can show textboxes and in one column you can show buttons. You can write table column Editing support/label providers to show the buttons.
With this approach you will be able show buttons for all rows or when you click on any cell you want to add or delete.
I can't share the code snippet right now, due to some reasons, but if you need I will share it on weekends

Cannot reduce size of RCP view when migrated to Eclipse 4

I'm currently working on migrating a set of eclipse RCP applications from 3.6 to 4.2.
I'm struggling with an issue with RCP perspectives that view height cannot be reduced below a certain size (looks like 10% from the window height).
The code works fine in eclipse 3.x and user can reduce the view height by dragging the border.
However, in 4.x the height of top most view (button view) can only be reduced upto a certain value.
Can anybody help with this, please?
public class Perspective implements IPerspectiveFactory {
public static final String ID = "im.rcpTest2.fixedperspective";
public void createInitialLayout(IPageLayout layout) {
String editorArea = layout.getEditorArea();
layout.setEditorAreaVisible(false);
layout.addStandaloneView(ButtonView.ID, false, IPageLayout.TOP,
0.1f, editorArea);
layout.addStandaloneView(View.ID, false, IPageLayout.LEFT,
0.25f, editorArea);
IFolderLayout folder = layout.createFolder("messages", IPageLayout.TOP,
0.5f, editorArea);
folder.addPlaceholder(View2.ID + ":*");
folder.addView(View2.ID+":2");
folder.addView(View2.ID+":3");
layout.getViewLayout(ButtonView.ID).setCloseable(false);
layout.getViewLayout(View.ID).setCloseable(false);
}
}
public class ButtonView extends ViewPart {
public ButtonView() {
}
public static final String ID = "im.rcptest2.ButtonView"; //$NON-NLS-1$
private Text text;
/**
* Create contents of the view part.
* #param parent
*/
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
container.setBackground(SWTResourceManager.getColor(SWT.COLOR_GRAY));
container.setLayout(new GridLayout(2, false));
text = new Text(container, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
{
Button btnMybutton = new Button(container, SWT.NONE);
btnMybutton.setText("MyButton");
}
}
#Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
This looks like the value
int minSashPercent = 10;
in org.eclipse.e4.ui.workbench.renderers.swt.SashLayout
There does not seem to be a way to change this value. So the only thing you could do would be to write a custom Sash Renderer class by providing your own Renderer Factory.

Adding header above of column titles in GWT datagrid

How can I add something like this in GWT datagird using CellTableBuilder?
This should work as a simply solution for provided case. Please replace "YourPage" to your real page, "YourClass" to your class and "yourColumn1", "yourColumn2" to your real columns, and "object.getYourColumnValue" to your real get value method. Please also don't forget to bind your data to the table (using: "ContactDatabase.get().addDataDisplay(dataGrid1);" as provided in showcase, or by "dataGrid1.setRowData(0, yourData);"
public class YourPage extends Composite {
...
// attributes
private Column<YourClass, String> yourColumn1;
private Column<YourClass, String> yourColumn2;
...
public DataGrid<YourClass> buildGrid() {
dataGrid1 = new DataGrid<YourClass>();
dataGrid1.setWidth("100%");
dataGrid1.setHeight("100%");
dataGrid1.setAutoHeaderRefreshDisabled(true);
// Generating columns
yourColumn1 = new Column<YourClass, String>(new TextCell()) {
#Override
public String getValue(YourClass object) {
return object.getYourColumnValue();
}
};
dataGrid1.addColumn(yourColumn1, "Column 1");
dataGrid1.setColumnWidth(0, 50, Unit.PCT);
yourColumn2 = new Column<YourClass, String>(new TextCell()) {
#Override
public String getValue(YourClass object) {
return object.getYourColumnValue();
}
};
dataGrid1.addColumn(yourColumn2, "Column 2");
dataGrid1.setColumnWidth(1, 50, Unit.PCT);
// setHeaderBuilder
dataGrid1.setHeaderBuilder(
new dataGrid1HeaderBuilder(
dataGrid1, false));
...
return dataGrid1;
}
// your private header builder class
private class dataGrid1HeaderBuilder extends AbstractHeaderOrFooterBuilder<YourClass> {
public tblValidatorsGroupsAnalysisResultsHeaderBuilder(
AbstractCellTable<YourClass> table, boolean isFooter) {
super(table, false);
setSortIconStartOfLine(false);
}
#Override
protected boolean buildHeaderOrFooterImpl() {
Style style = dataGrid1.getResources().style();
TableRowBuilder tr = startRow();
TableCellBuilder th = tr.startTH().colSpan(1);
th.style().trustedProperty("border-right", "10px solid yellow").cursor(Cursor.POINTER).endStyle();
th.text("Name").endTH();
// Your "Header" for 2 column
th = tr.startTH().colSpan(2);
th.text("Header").endTH();
// Add Column1 and Column2 headers
tr = startRow();
buildHeader(tr, new TextHeader("Column1"), yourColumn1, null, false, false, false);
buildHeader(tr, new TextHeader("Column2"), yourColumn2, null, false, false, false);
tr.endTR();
return true;
}
private void buildHeader(TableRowBuilder out, Header<?> header, Column<YourClass, ?> column,
Column<?, ?> sortedColumn, boolean isSortAscending, boolean isFirst, boolean isLast) {
Style style = dataGrid1.getResources().style();
boolean isSorted = (sortedColumn == column);
StringBuilder classesBuilder = new StringBuilder(style.header());
// Create the table cell.
TableCellBuilder th = out.startTH().className(classesBuilder.toString());
// Render the header.
Context context = new Context(0, 0, header.getKey());
renderSortableHeader(th, context, header, isSorted, isSortAscending);
// End the table cell.
th.endTH();
}
}
}

Setting ListGrid selection in SmartGWT

I'm trying to set the selected records of a ListGrid table object in SmartGWT, but I can't find any way of doing it. I know there's a getSelectedRecords() function, but no matching setSelectedRecords(). I tried to see if set/getSelectedState() would work, but GWT complains about needing a primary key and a DataSource object. Is there any way to set the selection of a ListGrid?
For this you can use one of the selectRecords() methods, like so:
public void onModuleLoad()
{
VLayout main = new VLayout();
final ListGrid grid = new ListGrid();
grid.setHeight(500);
grid.setWidth(400);
grid.setFields(new ListGridField("name", "Name"));
grid.setData(createRecords());
final IButton button = new IButton("Select some");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event)
{
grid.selectRecords(new int[]{2, 3}); //This will select index 2 and 3
}
});
main.addMember(grid);
main.addMember(button);
RootPanel.get().add(main);
}
private ListGridRecord[] createRecords()
{
return new ListGridRecord[]{
createRecord("monkey"),
createRecord("banana"),
createRecord("orange"),
createRecord("sun")
};
}
private ListGridRecord createRecord(String name)
{
ListGridRecord record = new ListGridRecord();
record.setAttribute("name", name);
return record;
}