SWT CCombo selected item highlight does not work - java

I have a combo viewer based on a CCombo:
public static ComboViewer createComboViewer(Composite parent) {
CCombo combo = new CCombo(parent, SWT.BORDER);
combo.setTextLimit(2);
combo.addVerifyListener(new UpperCaseKeyListener());
ComboViewer viewer = new ComboViewer(combo);
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setLabelProvider(new CustomLabelProvider());
String[] strings = {"AB","CD","EF","GH","IJ"};
viewer.getCCombo().addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent keyEvent) {
String key = viewer.getCCombo().getText();
System.out.println(key);
String[] items = viewer.getCCombo().getItems();
if (!key.equals("") && key.length()==2) {
for (int i=0;i<strings.length;i++) {
if (strings[i].contains(key)) {
final ISelection selection = new StructuredSelection(strings[i]);
viewer.setSelection(selection);
}
}
}
}
});
I have a list of strings : {"AB","CD","EF","GH","IJ"} in this combo viewer.
When I type for example "AB" my item is selected from the drop-down list , but it is not highlighted with blue.
How can I make this happen?
I want that when I type an item in the combo and it is found in the list , to be highlighted with blue when I open the drop down list.

You must call setInput on the viewer to tell it about your content:
String[] strings = {"AB","CD","EF","GH","IJ"};
viewer.setInput(string);
In general a viewer requires both the content provider and label provider to be set and then setInput to be called.

Related

GWT depending on browser scroll bar or dynamic resizing of callTable did not work

Iteresiting case which make my work a nightmare in GWT. I try to add to my panel tab with dynamic changed table to add some params by user. Requirements are dynamic adding new elements and that user can overview all of them and eventually correct it.
I create all that with callTable but in one browser (Chromium or Opera) I can add new elements but in the same time on the same package in mozzila I see scroll bar but canot add dynamically new elements, but if I erase some preloaded one new one appears. Can someone explain to me what exactly goes wrong as it is one package run in incognito mode with erased history and cookies after every session
Maybe screen will be helpfull- param fill added dynamically:
view with new element 1
table with scrool bar but without option of adding new element 2
And source code:
//initial layout and component
final VLayout customLayout = new VLayout();
Canvas customComponent = new Canvas();
//dataprovider modal creation with in memory list
final ListDataProvider<String> model = new ListDataProvider<>(
getProvisioningParameterList());
final CellTable<String> table = new CellTable<>();
// create column with data
Column<String, String> nameColumn = new Column<String, String>(new EditTextCell()) {
#Override
public String getValue(String object) {
return object;
}
};
//column with delete button
Column<String, String> deleteBtn = new Column<String, String>(
new ButtonCell()) {
#Override
public String getValue(String object) {
return "x";
}
};
// add column to the table
table.addColumn(nameColumn, "Custom parameters");
table.addColumn(deleteBtn, "Click to delete row");
//initialize table row size
table.setWidth("100%");
// Set the field updater, whenever user clicks on button row will be removed.
deleteBtn.setFieldUpdater(new FieldUpdater<String, String>() {
#Override
public void update(int index, String object, String value) {
model.getList().remove(object);
model.refresh();
table.redraw();
}
});
// add a data display to the table which is adapter.
model.addDataDisplay(table);
//add Button
final IButton addButton = new IButton("Add");
addButton.setIcon("icons/add.png");
addButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
model.getList().add("fill");
model.refresh();
table.redraw();
}
});
//add custom config panel with proper view
ScrollPanel sp = new ScrollPanel();
sp.setAlwaysShowScrollBars(true);
customComponent.setContents("Params");
customComponent.setAutoHeight();
customLayout.setMargin(15);
customLayout.addMember(customComponent);
customLayout.addMember(addButton, 1);
customLayout.addMember(saveButton, 2);
customLayout.addMember(table);
If someone will still wonder about it I got a solution. I forgot to add ScrollPanel to layout. Edit Additionally I put table into scrollPanel in specific dimentions and that two element structure to main VLayout. Now it works as expected :)

Gwt Button dropdown in celltable event handling on children

I have too many buttons in a table and I'd like to replace them by a button that open a dropdown list of actions. However I don't really know how to handle the events from the dropdown items. I manage to do it using a javascript function but it's not very practical because I can only pass primitive values.
I also want to make it as a custom cell in the future to use it in different pages in my project so returning some html isn't very practical.
Here's my code :
final ButtonCell buttonInfoCell = new ButtonCell();
Column<GwtStockProduct, String> buttonCell = new Column<GwtStockProduct, String>(buttonInfoCell) {
#Override
public void render(final Context context, final GwtStockProduct value, final SafeHtmlBuilder sb) {
Div div = new Div();
Div bG = new Div();
div.add(bG);
bG.addStyleName("btn-group");
Button button = new Button();
DropDownMenu dropDown = new DropDownMenu();
Span span = new Span();
span.addStyleName("caret");
span.setVisible(false);
button.add(span);
button.getElement().setAttribute("style", "background-image: none !important; background-color: #234C78 !important;");
// button.removeStyleName("");
button.addStyleName("btn-hide-icon btn-blue");
button.setDataToggle(Toggle.DROPDOWN);
button.setText("Change stock");
for (int i = 1; i < 5; ++i) {
AnchorListItem item = new AnchorListItem();
item.getElement().getFirstChildElement().removeAttribute("href");
item.getElement().getFirstChildElement().setAttribute("onclick", "triggerClick('" + i + "')");
item.setText("Item " + i);
dropDown.add(item);
}
// dropDown.getElement().setAttribute("style", "position: relative !important;");
bG.add(button);
bG.add(dropDown);
// sb.append(SafeHtmlUtils.fromTrustedString(buttonGroup));
sb.appendHtmlConstant(div.getElement().getInnerHTML());
}
#Override
public String getValue(final GwtStockProduct object) {
// TODO Auto-generated method stub
return null;
}
};
stockTable.addColumn(buttonCell, "Actions");
stockTable.setColumnWidth(buttonCell, 5, Unit.PCT);
I use SelectionCell to render a drop-down list of options. Maybe that will help you:
ArrayList<String> options = new ArrayList<String>();
options.add("choose an option..."); // the prompt text
options.add("option 1");
options.add("option 2");
// ...
final SelectionCell optionsCell = new SelectionCell(options);
Column<TableType, String> optionsColumn = new Column<TableType, String>(optionsCell) {
#Override
public String getValue(TableType object) {
return null;
}
};
optionsColumn.setFieldUpdater(new FieldUpdater<TableType, String>() {
#Override
public void update(int index, TableType object, String value) {
if(value == "option 1")
// process option 1
else if(value == "option 2")
// process option 2
// ...
// reset drop-down to show the prompt text
optionsCell.clearViewData(object);
redrawRow(index);
}
});
table.addColumn(optionsColumn, "options");
The first option is just a prompt text and after each selection change the drop-down list is reset to show the prompt.
The disadvantage is that you can not have different sets of options for different rows as the list is generated once for the whole column.

TreeTableView TableMenuButton setonAction

Is there any possible way to listen or to override the default TableMenuButton setonAction?
Something like this?
TreeTableView ttv = new TreeTableView();
ttv.setTableMenuButtonVisible(true);
ttv.setOnMouseClicked((MouseEvent event) -> {
....
});
I would like to know which column has been set to visible or invisible.
Any help is greatly appreciated.
I created an example about how to adapt the TableView's menu button. The TreeTableView is just similar. What you need to do is to get the ContextMenu. You can get it either by reflection or by using a lookup. Once you have it, you can do whatever you want with it.
I also filed a change request so that the context menu becomes accessible since the current implementation isn't satisfactory.
Here's the modified code of the lookup version:
public class TableUtils {
/**
* Make table menu button visible and replace the context menu with a custom context menu via reflection.
* The preferred height is modified so that an empty header row remains visible. This is needed in case you remove all columns, so that the menu button won't disappear with the row header.
* IMPORTANT: Modification is only possible AFTER the table has been made visible, otherwise you'd get a NullPointerException
* #param tableView
*/
public static void addCustomTableMenu( TreeTableView tableView) {
// enable table menu
tableView.setTableMenuButtonVisible(true);
// replace internal mouse listener with custom listener
setCustomContextMenu( tableView);
}
private static void setCustomContextMenu( TreeTableView table) {
TreeTableViewSkin<?> tableSkin = (TreeTableViewSkin<?>) table.getSkin();
// get all children of the skin
ObservableList<Node> children = tableSkin.getChildren();
// find the TableHeaderRow child
for (int i = 0; i < children.size(); i++) {
Node node = children.get(i);
if (node instanceof TableHeaderRow) {
TableHeaderRow tableHeaderRow = (TableHeaderRow) node;
// setting the preferred height for the table header row
// if the preferred height isn't set, then the table header would disappear if there are no visible columns
// and with it the table menu button
// by setting the preferred height the header will always be visible
// note: this may need adjustments in case you have different heights in columns (eg when you use grouping)
double defaultHeight = tableHeaderRow.getHeight();
tableHeaderRow.setPrefHeight(defaultHeight);
for( Node child: tableHeaderRow.getChildren()) {
// child identified as cornerRegion in TableHeaderRow.java
if( child.getStyleClass().contains( "show-hide-columns-button")) {
// get the context menu
ContextMenu columnPopupMenu = createContextMenu( table);
// replace mouse listener
child.setOnMousePressed(me -> {
// show a popupMenu which lists all columns
columnPopupMenu.show(child, Side.BOTTOM, 0, 0);
me.consume();
});
}
}
}
}
}
/**
* Create a menu with custom items. The important thing is that the menu remains open while you click on the menu items.
* #param cm
* #param table
*/
private static ContextMenu createContextMenu( TreeTableView table) {
ContextMenu cm = new ContextMenu();
// create new context menu
CustomMenuItem cmi;
// select all item
Label showAll = new Label("Show all");
showAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TreeTableColumn<?, ?>) obj).setVisible(true);
}
}
});
cmi = new CustomMenuItem(showAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// deselect all item
Label hideAll = new Label("Hide all");
hideAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TreeTableColumn<?, ?>) obj).setVisible(false);
}
}
});
cmi = new CustomMenuItem(hideAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// separator
cm.getItems().add(new SeparatorMenuItem());
// menu item for each of the available columns
for (Object obj : table.getColumns()) {
TreeTableColumn<?, ?> tableColumn = (TreeTableColumn<?, ?>) obj;
CheckBox cb = new CheckBox(tableColumn.getText());
cb.selectedProperty().bindBidirectional(tableColumn.visibleProperty());
cmi = new CustomMenuItem(cb);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
}
return cm;
}
}

have problems in Linking multiple JComboBox in JTable one time

I got a quite tricky problem when I do some code on JTable
I need to add one line In JTable when I click "Add" button, and I want one of the columns to render
as a JComboBox
the problem is that when I only add one line, it works fine.
but when I add multiple lines a time, no matter which combobox I choose item from, It will always trigger the last comboBox's event(seems always the same combobox since I have printed the hashcode of jComboBox in MyComboxActionListener class. it's the same).
why is that happens , I can't figure it out. Since It's totally a new comboBox and a new listener when I add one line.
Following is the code.
Thanks in advance.
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
ProducedProcedure_new addedProducedProcedure = new ProducedProcedure_new(); // the new item
componentProcedureTableModel.getWorks().add(addedProducedProcedure); //add one line to the table
componentProcedureTableModel.fireTableRowsInserted(componentProcedureTableModel.getRowCount()-1, componentProcedureTableModel.getRowCount()-1);
jTable1.changeSelection(componentProcedureTableModel.getRowCount()-1,0, false, false);
List<String> procedureNames = produceCardManager.getProcedureNames(componentIdTextField.getText().trim(),false); //get the items added to combobox
renderColumnAsCombox(1,procedureNames,addedProducedProcedure); //-------------------------------------------
}
void renderColumnAsCombox(int columnIndex , List<String> items,ProducedProcedure_new producedProcedure) {
TableColumn col = jTable1.getColumnModel().getColumn(columnIndex);
JComboBox comboBox = new JComboBox();
for(String item : items) {
comboBox.addItem(item);
}
MyComboxActionListener myComboxActionListener = new MyComboxActionListener(columnIndex,comboBox,producedProcedure);
comboBox.addActionListener(myComboxActionListener);
col.setCellEditor(new DefaultCellEditor(comboBox));
}
class MyComboxActionListener implements ActionListener { // listen for the select event of the combobox
private JComboBox jComboBox;
private ProducedProcedure_new producedProcedure;
private int columnIndex;
public MyComboxActionListener(int columnIndex,JComboBox jComboBox,ProducedProcedure_new producedProcedure) {
this.columnIndex = columnIndex;
this.jComboBox = jComboBox;
this.producedProcedure = producedProcedure;
}
#Override
public void actionPerformed(ActionEvent e) {
String selectedItem = (String)jComboBox.getSelectedItem();
producedProcedure.getProcedure().setProcedureName(selectedItem);
producedProcedure.getProcedure().setProcedureId(String.valueOf(produceCardManager.getProcedureId(selectedItem)));
producedProcedure.getProcedure().setFactor(produceCardManager.getProcedureFactor(selectedItem)); //automately update the factor
((ComponentProcedureTableModel_new)jTable1.getModel()).fireTableDataChanged();
}
}

How to add a ViewerFilter on a JFace TableViewer that update dynamically?

I want to add in a SWT/JFace application a search functionality that filter a TableViewer as the user enter text in the search text field.
final Text filterText = new Text(parent, SWT.NONE);
filterText.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent arg0) {
//TODO how to update the viewer filter with the new text ?
}
});
TableViewer tableViewer = new TableViewer(...);
ViewerFilter filterViewer = new ViewerFilter() {
#Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
if (filterText.getText() == "") {
return true;
}
//do my stuff to know if element need to be filtered or not
return false;
}
};
tableViewer.addFilter(filterViewer);
Do I need to remove the filter and create a new one in the modify listener or is there a better solution?
Basically, you need to have a way of passing the entered text to the filter, in your select method you should filter based on this text, and in your text widget's listener pass the text to the filter and call viewer.refresh() on your table.
This example should help you: http://www.vogella.com/tutorials/EclipseJFaceTableAdvanced/article.html#jfacetable_filter
org.eclipse.ui.dialogs.FilteredTree is specifically available for that purpose. Why can't you use that?

Categories