How to set EditTextBox into edit mode by program code? - java

I'm using GWT with a EditTextCell, which goes into edit mode on click.
Does anybody know a way of forcing the box into edit mode by program code?
Would I have to somehow fire a ClickEvent onto that box? Or how could this be done?

You can add the following method to your CellTable or DataGrid:
public void focus(final int row, final int column) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
getRowElement(row).getCells().getItem(column).getFirstChildElement().getFirstChildElement().focus();
}
});
}
Then you can simple call .focus(row, column) when you need to set focus on a given cell.
Or you can call .getRowElement()... directly, but I recommend wrapping it in a ScheduledCommand so it does not fire too early - before the cell is ready to accept focus.

It turned out I can fire a native click event on my cell as follows:
NativeEvent nativeevent = Document.get().createClickEvent(1, 0, 0, 0, 0, false, false, false, false);
cell.getElement().dispatchEvent(nativeevent);

You can also write render event or can add clickHandler for setting the contentEditable=true or false.
private class CustomEditCell extends EditTextCell {
public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<div contentEditable='true' unselectable='true' >"+value+"</div>");
}
}

Related

How to make cells in a column un-selectable

I have a JTable in which some columns are uneditable. I do that by overriding the isCellEditable method. I now want to make the cells in these columns un-selectable. if the user is using the tab key to go through the cells, I want to focus to "skip" these uneditable cells. Can you please tell me how this is done? Thanks.
All navigation behaviour is controlled by actions registered in the table's actionMap. So the way to go is to hook into the action that is bound to the tab key, implement a wrapper that invokes that action as often as needed and replace the original action with the wrapper.
A raw code snippet for skipping not-editable cells:
Object actionKey = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.get(KeyStroke.getKeyStroke("TAB"));
final Action traverseAction = table.getActionMap().get(actionKey);
Action wrapper = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
traverseAction.actionPerformed(e);
while(shouldRepeat((JTable) e.getSource())) {
traverseAction.actionPerformed(e);
}
}
private boolean shouldRepeat(JTable source) {
int leadRow = source.getSelectionModel().getLeadSelectionIndex();
int leadColumn = source.getColumnModel().getSelectionModel().getLeadSelectionIndex();
return !source.isCellEditable(leadRow, leadColumn);
}
};
table.getActionMap().put(actionKey, wrapper);

Change default keybinding for TableViewer

By default a JFace TableViewer moves the selection up and down when the user presses the up or the down arrow key. This makes sense most of the time, but in my application the business logic will be different.
How can I override this behavior? I tried adding a KeyListener and it gets called, but the default action still happens: selection changes.
I have figured out I have to use a TableViewerFocusCellManager along with a CellNavigationStrategy. I expected the FocusCellManager to be a property of the TableViewer, but it is not. Apparently the FocusCellManager does the wiring behind the scenes.
CellNavigationStrategy navigationStrategy = new CellNavigationStrategy() {
#Override
public boolean shouldCancelEvent(ColumnViewer viewer, Event event) {
return true;
}
#Override
public boolean isNavigationEvent(ColumnViewer viewer, Event event) {
return false;
}
};
TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer, new FocusCellOwnerDrawHighlighter(tableViewer), navigationStrategy);

JTable: single selection for the user, multiple selections programmatically

I have a JTable where the user should be able to select only a single row, but whenever a row is selected by the user, some other rows (that are related according to some logic) should also be selected programmatically. The problem is that if I set the selection mode of the table to ListSelectionModel.SINGLE_SELECTION, addRowSelectionInterval will also select only one row. Any ideas?
EDIT: I think all ideas (custom selection model, clearing all but last user selections, custom renderer for highlighting) were good, but the best is to use SwingX, because it doesn't require much infrastructure-code, only a clever usage of the library. (and it's easy to be clever when a SwingX-guru is helping :)
Biased me would say: certainly much easier in SwingX :-)
All you need is
a custom HighlightPredicate which decides about what is related
a ColorHighlighter configured with the selectionColors
set the custom predicate on receiving change notification from the selection model
Some code:
// the custom predicate
public static class RelatedHighlightPredicate implements HighlightPredicate {
List<Integer> related;
public RelatedHighlightPredicate(Integer... related) {
this.related = Arrays.asList(related);
}
#Override
public boolean isHighlighted(Component renderer,
ComponentAdapter adapter) {
int modelIndex = adapter.convertRowIndexToModel(adapter.row);
return related.contains(modelIndex);
}
}
// its usage
JXTable table = new JXTable(someModel);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
final ColorHighlighter hl = new ColorHighlighter(HighlightPredicate.NEVER,
table.getSelectionBackground(), table.getSelectionForeground());
table.addHighlighter(hl);
ListSelectionListener l = new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
invokeUpdate((ListSelectionModel) e.getSource());
}
private void invokeUpdate(final ListSelectionModel source) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int singleSelection = source.getMinSelectionIndex();
if (singleSelection >= 0) {
int first = Math.max(0, singleSelection - 2);
int last = singleSelection + 2;
hl.setHighlightPredicate(new RelatedHighlightPredicate(first, last));
} else {
hl.setHighlightPredicate(HighlightPredicate.NEVER);
}
}
});
}
};
table.getSelectionModel().addListSelectionListener(l);
You might set multiselection possible for the table, but with each selection change - take only 1 (last selected) row, clear other selections and add your own computed selection.
The problem is that if I set the selection mode of the table
use ListSelectionModel.SINGLE_SELECTION for events came from mouse and keyborad
some other rows (that are related according to some logic) should also be selected programmatically
have look at Renderer for JTable, then required row(s), columns or whatever could be highlighted until programmatic rules stay unchanged
... maybe will help you

Get GWT DialogBox absolute position - onLoad/onAttach/show do not helps

I am stuck in getting an absolute position of DialogBox. I know it is the common problem (and strange workaround) for PopupPanel (which is parent to DialogBox) to set it, but what if I want to get it, what is the exact moment when the box attached to DOM? Neither overriding show nor onAttach nor show does not help:
class MyDialog extends DialogBox {
public MyDialog(. . .) {
ComplexPanel vert = new VerticalPanel();
vert.add("Test");
vert.add(new Button("Close", new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
MyDialog.this.hide();
}
}));
setWidget(vert);
this.addAttachHandler(new AttachEvent.Handler() {
#Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) Log.debug("attach:"+MyDialog.this.getAbsoluteLeft() +";"+
MyDialog.this.getAbsoluteTop());
}
});
}
#Override
protected void onLoad() {
super.onLoad();
Log.debug("load:"+this.getAbsoluteLeft() +";"+this.getAbsoluteTop());
}
#Override
public void show() {
super.show();
Log.debug("show:"+this.getAbsoluteLeft() +";"+this.getAbsoluteTop());
}
}
So when I call new MyDialog().show();, all this lines do log 0;0, however dialog is positioned in center of a page. But what I want is the sum of the chain of offsetParent positions. (And they are 0 in these moments even in JavaScript, if use JSNI to check this)
Again, setPopupPositionAndShow allows to set position but not get it :(
Finally, I've got this to work:
#Override
public void setPopupPosition(int left, int top) {
super.setPopupPosition(left, top);
if (this.isAttached()) Log.debug("setPos:"+this.getAbsoluteLeft() +";"+this.getAbsoluteTop());
}
It gets the proper position and I hope it is the right way to do it and setPopupPosition is called every time. You will even call it manually when using setPopupPositionAndShow.
I think it will be wise to let this question stay at SO "for future generations".
Upd. If you plan to call center(...) or some similar method of your dialog, be aware that setPopupPosition will be called twice or more times (may be first time with 0, 0), even if you'll check if it isAttached(). Add some additional check to ensure that positions are correct in current call.

GWT SuggestBox: How do I force the SuggestBox to select the first item in the suggestion list?

I have a textbox and one suggestbox. I attach a value change and key up handler to the text box such that whatever the user types (or pastes) into the text box is echo-ed inside the suggestbox. I can get the suggestbox to display the suggestion list by calling showSuggestionList on each value change and key up event.
Now, how do I get the suggestbox to automatically choose the first item in the suggestion list?
One of the methods I tried is to programatically simulate key presses, i.e
suggestBox.setFocus(true);
NativeEvent enterEvent = Document.get().createKeyPressEvent(false, false, false, false, KeyCodes.KEY_ENTER);
DomEvent.fireNativeEvent(enterEvent, suggestBox);
textBox.setFocus(true);
This doesn't work at all. The enter key isn't simulated. Another possible solution is to extend SuggestionBox.SuggestionDisplay, but I'm not too sure how to that. Any pointers appreciated.
Update: I'm still working on this and trying various methods.
Here, I tried to implement my own SuggestionDisplay by subclassing DefaultSuggestionDisplay and overriding getCurrentSelection() to make accessible from my class. This doesn't work either. Null is returned.
private class CustomSuggestionDisplay extends DefaultSuggestionDisplay {
#Override
protected Suggestion getCurrentSelection() {
return super.getCurrentSelection();
}
}
suggestBox.setAutoSelectEnabled(true);
textBox.addKeyUpHandler(new KeyUpHandler() {
public void onKeyUp(KeyUpEvent event) {
suggestBox.setValue(textBox.getText(), true);
suggestBox.showSuggestionList();
if (suggestBox.isSuggestionListShowing()) {
String s = ((CustomSuggestionDisplay) suggestBox.getSuggestionDisplay()).getCurrentSelection().getDisplayString();
Window.alert(s);
}
}
});
Here, I tried to attach a value change handler to the SuggestBox, and casting the event type to SuggestOracle.Suggestion. Again, null is returned.
suggestBox.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String s = ((SuggestOracle.Suggestion) event).getDisplayString();
Window.alert(s);
}
});
Use suggesBox.setAutoSelectEnabled(true)
Here more info about the SuggestBox of GWT:
You could try using addSelectionHandler in conjunction with setAutoSelectEnabled to receive an event whenever a suggestion is selected. You could also have your Oracle send a message when it suggests something, or your Display send a message when it displays a list:
public class AutomaticallySelectingSuggestionDisplay extends SuggestBox.DefaultSuggestionDisplay {
#Override
protected void showSuggestions(SuggestBox box, Collection<? extends SuggestOracle.Suggestion> suggestions, boolean isDisplayHtml, boolean isAutoSelectEnabled, SuggestBox.SuggestionCallback callback) {
super.showSuggestions(box, suggestions, isDisplayHtml, isAutoSelectEnabled, callback);
fireValueChangeEventWithFirstSuggestion(suggestions);
}
}
This idea feels a little muddled to me, so I hope you can find a solution just using event handlers.

Categories