I want to use GWT-Bootstrap Tooltip for cells of a column in the CellTable. Each Tooltip will show description of a cell which is a field in the "MyCustomObject" class used for generating the table.
One of the quick solutions I found in one of the answers on this question is the following.
CellTable<MyCustomObject> table = new CellTable<MyCustomObject>();
table.addCellPreviewHandler(new Handler<MyCustomObject>() {
#Override
public void onCellPreview(CellPreviewEvent<MyCustomObject> event) {
if (event.getNativeEvent().getType().equals("mouseover")){
table.getRowElement(event.getIndex()).getCells()
.getItem(event.getColumn()).setTitle(event.getValue().getDescription());
}
}
}
);
It makes a little sense but I don't see anything when I hover the cursor over the table cells and nothing is attached to the DOM. Can anyone explain how this even works? I want to attach the Tooltip to table cell similar to the following.
Tooltip tt = new Tooltip("Here goes the description");
tt.setAnimation(true);
tt.setWidget(tableColumn);
tt.reconfigure();
The problem is that a CellTable cell is not a widget so it can't be attached in that way.
So is there any workaround for this?
I've faced this issue once and I created my own cell that displays a tooltip, here's how I did it: Note: My cell was displaying an image with a tooltip so I quickly changed the code to display String text... So I did not test it with text.
private class TooltipCell extends AbstractCell<String> {
private String tooltipText = "";
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendHtmlConstant("<div title=\"" + tooltipText + "\">");
sb.append(SafeHtmlUtils.fromString(value));
}
}
public void setTooltip(String tootltipTextToSet){
tooltipText = tootltipTextToSet;
}
}
And in your table use method setTooltip("tooltip text") in method getValue just before returning the cell text.
Hope this helps
Related
I'm looking for a way to display a tree in the first column of a table/grid with three other columns, one with a combobox and the others with checkboxes. I've been trying to make this work with a TreeViewer but it doesn't quite fit what I'm looking for. The tree goes together fine. The Combobox column where I used the EditorSupport for the column and return a ComboboxCellEditor in the getCellEditor method but you can only see that there is a combobox in the column when you select a cell in that column. Then when you click out of the cell the selected value goes back to the default blank. The same goes for the checkbox columns where it is is only visible when the cell is selected. I'm looking for something that will display my tree with the combobox column and checkbox columns always visible. I've looked at TableViewer but couldn't find a way to force in a tree in the first column. I've looked at Nebula Grid but that doesn't look like it supports comboboxes. Any tips on how to get one of these to work like what I am looking for or if there is some other tree/table/grid I should be looking at. Thanks.
Edit: Here's the code for the EditingSupport class.
private class ComboBoxEditingSupport extends EditingSupport
{
private ComboBoxCellEditor cellEditor;
public ComboBoxEditingSupport(ColumnViewer viewer)
{
super(viewer);
cellEditor =
new ComboBoxCellEditor(((TreeViewer) viewer).getTree(),
new String[] {
"Some String",
"Some other String" }, SWT.READ_ONLY);
}
#Override
protected CellEditor getCellEditor(Object element)
{
if (element instanceof MyObject
{
return cellEditor;
}
return null;
}
#Override
protected boolean canEdit(Object element)
{
if (element instanceof MyObject
{
return true;
}
return false;
}
#Override
protected Object getValue(Object element)
{
return 0;
}
#Override
protected void setValue(Object element, Object value)
{
TreeItem[] ti = treeViewer.getTree().getSelection();
CCombo combo = ((CCombo) cellEditor.getControl());
String str = combo.getItem(combo.getSelectionIndex());
ti[0].setText(1, str);
}
}
Your setValue method must update the value in your model data (the data returned by your content provider). The element parameter to setValue is the particular model data object (MyObject) that you should update.
After updating the value call:
getViewer().update(element, null);
to get the tree to update the display from the model.
Trying to update the TreeItem directly will not work.
Vaadin Grid allows to be defined as editable with
grid.setEditorEnabled(true);
This makes all visible columns editable. However I don't want the user to edit an specific column, but seems like the editable is an all or nothing.
The next best solution I have found is to define an editor field with a disabled editor, which almost does the trick but the user is still able to select the text and move the cursor (but the field is not editable anymore).
Grid.Column nameColumn = grid.getColumn("fullName");
nameColumn.setHeaderCaption("Full Name");
nameColumn.setEditorField(getNoEditableTextField());
...
private Field<?> getNoEditableTextField() {
TextField noEditableTextFiled = new TextField();
noEditableTextFiled.setEnabled(false);
return noEditableTextFiled;
}
I believe Label cannot be used because it's not a Field.
Is there a better option to achieve this?
edit: as aakath said, there is a way of achieving this not enabling the column to be edited, but in doing so the cell value disappears when you edit the row, which is not desirable.
Did you try calling setEditable(false) method on the column? I believe it should make the field non-editable when the item editor is active.
grid.getColumn("fullName").setEditable(false);
my solution is below. i have just finished. it was not tested too much. but it may give you some ideas.
ati
getColumn(columnName).setEditable(true).setEditorField(getNoEditableField(columnName));
...
private Field<?> getNoEditableField(final String columnName) {
CustomField<Label> result = new CustomField() {
#Override
protected Component getContent() {
Label result = (Label) super.getContent();
Object editedItemId = getEditedItemId();
String value = DEFAULT_VALUE;
if (editedItemId != null) {
value = CustomizableGrid.this.toString(getContainerDataSource().getItem(editedItemId).getItemProperty(columnName).getValue());
}
result.setValue(value);
return result;
}
#Override
protected Component initContent() {
Label result = new Label(DEFAULT_VALUE, ContentMode.HTML);
result.setDescription(getColumnDescription(columnName));
result.setStyleName("immutablegridcellstyle");
return result;
}
#Override
public Class getType() {
return Label.class;
}
};
result.setConverter(new Converter<Label, Object>() {
//converter for your data
});
return result;
}
I had the same problem and didn't want that clicking on id column opens editor. I solved it with adding an ItemClickListener as below. It works fine for me.
grid.addItemClickListener((ItemClickListener<GridBean>) event -> grid.getEditor().setEnabled(!event.getColumn().getCaption().equals("Id")));
Also byc clicking on specific columns Grid is not editable any more.
There is one tricky way to do it! I've just found out it.
So, first of all you need to use grid with container, instead of direct rows adding:
BeanItemContainer<MyBean> container = new BeanItemContainer<>(MyBean.class);
setContainerDataSource(container);
Then remove fields setters from MyBean, except setters for fields what you have to edit.
I think the same can be achieved by making the grid an editable one by grid.setEditorEnabled(true); and disabling editing option for other columns like grid.getColumn(columnName).setEditable(false);. But I am not sure of any demerits of this method. Any suggestion is always appreciated.
Its simple just go to Vaadin Documentation what did from it is below:
you can see here I gave a specified column Name
grid = new Grid<>();
lst = new ArrayList<>();
provider = new ListDataProvider<>(lst);
lst.add(new Company(1, "Java"));
grid.setDataProvider(provider);
grid.addColumn(Company::getSerialNo).setCaption("Sr.no");
TextField tf = new TextField();
grid.getEditor().setEnabled(true);
HorizontalLayout hlyt = new HorizontalLayout();
grid.addColumn(Company::getName).setEditorComponent(tf, Company::setName).setCaption("Name").setExpandRatio(2);
hlyt.addComponent(grid);
I use the following approach to get a read-only field, the trick is override the setEnabled method to get a disabled textfield. If you trace the source code in Vaadin Grid, no matter what field you pass to a Grid, it will always call the field.setEnabled(true).
myGrid.getColumn(propertyId).setEditorField(new ReadOnlyField());
And
public class ReadOnlyField extends TextField
{
public ReadOnlyField()
{
super();
this.setReadOnly(true);
}
#Override
public void setEnabled(boolean enabled)
{
// always set to disabled state
super.setEnabled(false);
}
}
I have a JTable and some editable cells which are dynamically formatted with very specific HTML based on some business rules.
However, when you edit these cells all the HTML is in the CellEditor. I just want the plain text in the CellEditor.
I am trying to do this to the entire table. Here is the code I used. I threw together an extended DefaultCellEditor but its still showing the HTML. I don't even see the debugger entering the getCellEditorValue() method. What do I do?
public class MyTable extends JTable
{
public MyTable()
{
MyTable.setCellEditor(new DefaultCellEditor(new JTextField())
{
#Override
public Object getCellEditorValue() {
// get content of textField
String str = (String) super.getCellEditorValue();
if (str == null) {
return null;
}
if (str.length() == 0) {
return null;
}
//remove HTML and return plain text
return Jsoup.parse(str).text();
}
});
}
}
I'm not sure where things are going awry; a complete example may shed some light. The normal editing sequence is outlined here, suggesting that you should probably create your own renderer and editor:
class MyRenderer extends DefaultTableCellRenderer {…}
class MyEditor extends DefaultCellEditor {…}
and apply them as follows:
table.setDefaultRenderer(String.class, new MyRenderer());
table.setDefaultEditor(String.class, new MyEditor());
Be certain that your TableModel returns the correct type token from getColumnClass().
I'd like to know, if it is possible to render simple HTML tags in JavaFX TableView (b, i, subscript, supscript). In my code snippet I used default cellValueFactory, but maybe someone could tell me if exists any cell factory which allow me to display html.
From code:
class Data{
private String row = "<b> Sample data</b>"
public String getRow(){
return row;
}
TableView<Data> tableView = new TableView();
TableColumn<Data,String> column = new TableColumn("Sample Column");
column.setCellValueFactory(new PropertyValueFactory<Data, String>("row"));
tableView.getColumns().addAll(column);
I wish I could see Sample Data in my table in bold. Thanks in advance!
--UPDATE
Code that allows me to see my HTML, but resizes table cell, WebView size is ignored and not wrapped tight
private class HTMLCell extends TableCell<Component, Component> {
#Override
protected void updateItem(Component item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
WebView webView = new WebView();
webView.setMaxWidth(200);
webView.setMaxHeight(50);
WebEngine engine = webView.getEngine();
// setGraphic(new Label("Test"));
setGraphic(webView);
String formula = item.getFormula();
engine.loadContent(formula);
}
}
}
TableColumn<Component, Component> formulaColumn = new TableColumn<>("Formula");
formulaColumn.setMinWidth(300);
formulaColumn.setCellFactory(new Callback<TableColumn<Component, Component>, TableCell<Component, Component>>() {
#Override
public TableCell<Component, Component> call(TableColumn<Component, Component> param) {
return new HTMLCell();
}
});
formulaColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Component, Component>, ObservableValue<Component>>() {
#Override
public ObservableValue<Component> call(CellDataFeatures<Component, Component> param) {
return new SimpleObjectProperty<Component>(param.getValue());
}
});
HTML in a WebView in a TableCell
You have to make your own cell factory which returns a WebView node into which you load your HTML content.
On Correctly Sizing the WebView
In terms of establishing the preferred size of the WebView node, that is a little tricky. It would be simpler if RT-25005 Automatic preferred sizing of WebView were implemented.
I think the sample code from your question will work if you just replace the maxSize setting for the WebView with a webView.setPrefSize(prefX, prefY) call. You will just have to guess what the prefX and prefY values should be as I don't know a good way of determining programmatically.
I think your code should work by setting the max size for the WebView, but the WebView doesn't seem to respect the max size setting and just uses the pref size setting, which I think may be a bug in Java 8b129 (you could file that in the JavaFX Issue Tracker with a minimal, executable test case which reproduces it and a description of your test environment).
TextFlow Alternative
You might also consider using TextFlow component for representing your styled text. It is not HTML, but if all you want to do is some simple styling like making some text in the cell bold or italic, it might be a good option.
Use HTML tables in WebEngine/WebView rather than TableView.
Table examples
i needed an Widget to display text properly, containing HTML elements. Therefore i used the GWT HTML-Widget like that.
HTML text= new HTML(new SafeHtml() {
#Override
public String asString() {
return "<b>TestText</b>";
}
});
Now i would like to select text displayed by that widget, and somehow get the String.
I would like to right click the marked text, and do something with that String
It's also no problem if your ideas making use of other gwt widgets, i am not too focused on that HTML one.
I also have access to Sencha GXT libarys.
Any ideas would be appreciated.
I'm assuming you want the user to select text and then retrieve the selected text on right click. Am I right? I don't recall any way of retrieving selected text in GWT, so I would use pure javascript for that. There is already a thread explaining how to do that with javascript, so you can grab that code and wrap it in a JSNI method:
public class MyClass implements IsWidget {
private final HTML text;
public MyClass() {
text = new HTML(SafeHtmlUtils.fromTrustedString("<b>Some text</b>"));
text.addDomHandler(new ContextMenuHandler() {
#Override
public void onContextMenu(ContextMenuEvent event) {
String test = getSelection();
Window.alert(test);
}
}, ContextMenuEvent.getType());
}
private native String getSelection() /*-{
var text = "";
if ($wnd.getSelection) {
text = $wnd.getSelection().toString();
} else if ($doc.selection && $doc.selection.type != "Control") {
text = $doc.selection.createRange().text;
}
return text;
}-*/;
#Override
public Widget asWidget() {
return text;
}
}
You can use sth like this:
final Label label = new Label("Some text");
label.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
label.getElement().getStyle().setBackgroundColor("#ff0"); //sth. like select
String txt = label.getText(); //get the String
Window.alert(txt); //do sth. with text
}
});
But it works on left click. If you have to use right click, you can use native JS code using eg. jQuery click.
And do not use b tag. It is deprecated in HTML5.
I've actually found a GWT-Libary that can get the selected text.
Watch this https://code.google.com/p/gwt-selection/
After installing the libary i just had to
String currentSelection = Selection.getBrowserRange().getText();
Thank you for answering though - you helped me a lot