How to access the currently selected item within Wicket Palette - wicket

I am trying to override certain features of the Wicket Palette. I have attached a picture of what i am trying to accomplish with Palette. Basically in addition to the select-item-clickbutton-moveToRight functionality of Palette, I also want to know which item has been selected before it is moved. When I select an item in either of the panels and click on a View button, I should be able to display an html page related to the currently selected item from the Palette.
Right now, the button is placed out of the Palette code and as long as I can get the ID of the selected element, I will be able to accomplish my objective.
I am stuck at the point where I need to know which item has been selected within the palette.
Here's what I have tried so far:
1. Adding an onclick listener to the choicesComponent using the AjaxFormComponentUpdatingBehavior
final Palette classFormMapping = new Palette("formsPalette", new ListModel(selectedFormsList),
formsList, new CustomObjectChoiceRenderer(), 8 , false ){
#Override
protected void onBeforeRender() {
super.onBeforeRender();
getChoicesComponent().add(new AjaxFormComponentUpdatingBehavior("onclick"){
#Override
protected void onUpdate(AjaxRequestTarget target) {
System.out.println("REACHED HERE"+ getFormComponent());
/*
* The code reaches here for each click but I am unable to know which item was selected */
}
});
}
};
Adding a Recorder component to the Palette with an "onclick" listener.
This listener does not get called at all.
final Palette classFormMapping = new Palette("formsPalette", new ListModel(selectedFormsList),
formsList, new CustomObjectChoiceRenderer(), 8 , false ){
protected Recorder newRecorderComponent() {
Recorder recorder = super.newRecorderComponent();
recorder.add(new AjaxFormComponentUpdatingBehavior("onclick") {
private static final long serialVersionUID = 1L;
#Override
protected void onUpdate(AjaxRequestTarget target) {
System.out.println("reached record on click ");
}
});
return recorder;
}
};
Trying to create this palette with a custom button
Please help. Thanks in advance.

Palette.java javadoc explains how to "Ajax-ify" it: https://github.com/apache/wicket/blob/529db58c413861677f7ff6736f9363edf42ae85a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/Palette.java#L52-L71
But this won't help you because the selection is done at the client side first and then Wicket is notified:
https://github.com/apache/wicket/blob/529db58c413861677f7ff6736f9363edf42ae85a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/palette.js#L118-L127
You need either to register your own JS event listener for 'change' event before the Wicket one or monkey-patch palette.js to override Wicket.Palette.updateRecorder() function.

Related

E4: drag an object from a TableViewer to Windows Explorer (or OS specific file system)

In my Eclipse RCP application I display some business data in a TableViewer.
I want the user to be able to drag a row from the table viewer and drop it on the windows desktop/explorer. Windows should then create a file with the data from the selected row that I could provide in the dragSetData(..) method of the DragSourceAdapter class.
How to implement this? It seems that using FileTransfer as the dragSourceSupport on the table viewer is the way to go as it trigger a call to the dragSetData() method. But what object should I create and assign to "event.data" in this method?
A working example would be appreciated.
I've implemented the reverse without problem, i.e. drag a file from windows explorer onto the TableViewer and add a row in the table. There are plenty on sample for this on the net but can't find a sample of the opposite, drag from eclipse to the OS
[edit + new requirement]
So I understand that I have to create a temporary file somewhere and set the name of that temp file in event.data in dragSetData()
Q: is there a simpler way to do that, eg set somewhere (iun data) the content of the file directly without the temp file?
There is another requirement. When the drop operation is about to occur, I want to show a popup to the user that will have to choose what "business data" from the "row" he wants to export and the name of the file that will be created. I tried the following (only asking for the filename for now) but it does not work as expected as the popup shows up as soon as the cursor reach the first pixel outside my app. I would like to show the popup just "before" the drop operation occurs.
Q: is there a way to have this popup show just before the drop operation occurs, ie when the user "release" the mouse button?
#Override
public void dragSetData(final DragSourceEvent event){
if (FileTransfer.getInstance().isSupportedType(event.dataType)) {
// Will be a more complex dialog with multiple fields..
InputDialog inputDialog = new InputDialog(shell, "Please enter a file name", "File Name:", "", null);
if (inputDialog.open() != Window.OK) {
event.doit = false;
return;
}
event.data = new String[] { inputDialog.getValue() };
}
}
The event.data for FileTransfer is an array of file path strings.
You DragSourceAdapter class might look something like:
public class MyDragSourceAdapter extends DragSourceAdapter
{
private final StructuredViewer viewer;
public MyDragSourceAdapter(final StructuredViewer viewer)
{
super();
this.viewer = viewer;
}
#Override
public void dragStart(final DragSourceEvent event)
{
IStructuredSelection selection = viewer.getStructuredSelection();
if (selection == null)
return;
// TODO check if the selection contains any files
// TODO set event.doit = false if not
}
#Override
public void dragSetData(final DragSourceEvent event)
{
if (!FileTransfer.getInstance().isSupportedType(event.dataType))
return;
IStructuredSelection selection = viewer.getStructuredSelection();
List<String> files = new ArrayList<>(selection.size());
// TODO add files in the selection to 'files'
event.data = files.toArray(new String [files.size()]);
}
}
and you install it on your viewer with:
MyDragSourceAdapter adapter = new MyDragSourceAdapter(viewer);
viewer.addDragSupport(DND.DROP_COPY, new Transfer [] {FileTransfer.getInstance()}, adapter);

Custom Perspective Switcher Toolbar: How can I dynamically update it?

I'm trying to implement a custom perspective switcher toolbar to replace eclipse's built-in one. I couldn't get the toolbar to display, and it was shown to me that due to a bug with the dynamic element in a menu contribution, I have to use a control element instead, as described in the workaround to the dynamic bug.
I have a toolbar displaying following that approach, but I cannot figure out how to update it dynamically. The workaround instruction is to call ContributionItem#fill(CoolBar, int) from my WorkbenchControlContributionItem's update method instead of doing the fill in the createControl method.
I don't know who is supposed to call update, but it never gets invoked no matter what I do. I have a perspective listener which knows when to update the toolbar, so from that listener's callback I call fill(CoolBar, int). But I wasn't sure how to get the CoolBar to pass to that method, so I created one on the current shell.
The end result of all this is that the toolbar displays the correct number of items initially, but when I need to add an item, it has no effect. I call fill(CoolBar, int) and it adds the new item to the toolbar, but everything I've tried to make the CoolBar and ToolBarupdate does not work. When I re-launch the app, the toolbar has the added item.
I'm sure I'm doing this wrong, but I can't figure out the right way. Here's an elided representation of my code (omitting methods, layout code, etc not related to the update problem).
public class PerspectiveSwitcherToolbar extends WorkbenchWindowControlContribution implements IPerspectiveListener {
...
#Override
protected Control createControl(Composite parent) {
this.parent = parent;
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
page.getWorkbenchWindow().addPerspectiveListener(this);
toolBarManager = (ToolBarManager)parent.getParent().getData();
fTopControl = new Composite(parent, SWT.BORDER);
fill(new CoolBar(page.getWorkbenchWindow().getShell(), SWT.HORIZONTAL), -1);
return fTopControl;
}
#Override
public void fill(CoolBar coolbar, int index) {
IPerspectiveDescriptor[] openPerspectives = page.getOpenPerspectives();
String activePerspective = getPerspectiveId();
ToolBar toolbar = new ToolBar(fTopControl, SWT.NONE);
for(IPerspectiveDescriptor descriptor : openPerspectives) {
ToolItem item = new ToolItem(toolbar, SWT.RADIO);
//overkill here, trying to find some way to upate the toolbar
toolbar.update();
parent.update();
parent.layout(true);
parent.getParent().update();
parent.getParent().layout(true);
coolbar.layout(true);
}
//PerspectiveListener callback
#Override
public void perspectiveActivated(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
fill(new CoolBar(page.getWorkbenchWindow().getShell(), SWT.HORIZONTAL), -1);
if (page.getWorkbenchWindow() instanceof WorkbenchWindow){
//this non-API call doesn't help either
((WorkbenchWindow) page.getWorkbenchWindow()).updateActionBars();
}
}
...
}

How to close Dialog that uses AbstractDialogAction

I am working on Netbeans building a JavaFX application.
I started using ControlsFX (http://fxexperience.com/controlsfx/)
I have implemented a simple Dialog that uses custom AbstractDialogAction s as I want specific number of buttons to appear.
I do this like this:
Action a = new AbstractDialogAction(" button a ", Dialog.ActionTrait.CLOSING) {
#Override
public void execute(ActionEvent ae) {
}
};
ArrayList<Action> actions = new ArrayList<>();
actions.add(a);
actions.add(b); // other button
actions.add(c); // another button
dialog.actions(actions);
Action response = dialog.showConfirm();
Dialog is shown correctly with the given buttons.
My question is how to force the Dialog to close when a button is pressed ?
I thought setting a Dialog.ActionTrait.CLOSING would do the trick, but the Dialog stays open.
From eugener in ControlsFX mailing list
public void execute(ActionEvent ae) {
if (ae.getSource() instanceof Dialog ) {
((Dialog) ae.getSource()).setResult(this);
}
}
The above sets the result of the Dialog to be the current Action and closes the Dialog
But maybe that is a little redundant as I can simply call:
((Dialog) ae.getSource()).hide();
.hide() hides the Dialog and also sets the current action as the result.
I can't suggest which is a better solution (hide() was suggested by jewelsea)
In addition I would suggest to always override the toString() method of class AbstractDialogAction, in order to get readable result from:
Action response = dialog.showConfirm();
System.out.println("RESPONSE = "+ response.toString());
Hide the dialog to close it => dialog.hide()

Block gwt DisclosurePanel on open state

How may I block a gwt DisclosurePanel on the open state ?
I mean, how can I prevent this DisclosurePanel to close if the user click the header more than once ?
(My header is a textBox, I want the user to enter a text, and the panel should remain open if the user unfocus the textBox and focus newly by clicking it. The DisclosurePanel content has a "cancel" button that closes the panel)
Thank you very much.
I edit my question after 2 first answers: I would like to avoid to reopen the DisclosurePanel once closed to avoid flashing effect. I actually want to prevent the DisclosurePanel to close. Maybe sinkEvents can help me... if so, how? Thanks.
A NativePreviewHandler receives all events before they are fired to their handlers. By registering a nativePreviewHandler the first time your disclosurePanel is opened, you can cancel the click event. You can later decide to remove this handler by preventClose.removeHandler();
HandlerRegistration preventClose = null;
....
panel.addOpenHandler(new OpenHandler<DisclosurePanel>() {
#Override
public void onOpen(OpenEvent<DisclosurePanel> event) {
if (preventClose == null){
preventClose = Event.addNativePreviewHandler(new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (event.getTypeInt()==Event.ONCLICK && event.getNativeEvent().getEventTarget() == panel.getHeader().getElement().cast())
event.cancel();
}
});
}
}
});
The obvious answer is review the javadoc here: https://google-web-toolkit.googlecode.com/svn/javadoc/1.5/com/google/gwt/user/client/ui/DisclosurePanel.html
There is a setOpen() method that: Changes the visible state of this DisclosurePanel.
Set it to false from a click event to capture the user action.
The JavaDoc is right here: https://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/ui/DisclosurePanel.html
jamesDrinkard pointed the old 1.5 javadoc.
You can use the addCloseHandler(CloseHandler<DisclosurePanel> handler) method to add a handler so when the user tries to close it you can reopen it again with setOpen().
Maybe not the best way, but it worked for me (maybe just one of both will work too):
dPanel.setOpen(true);
dPanel.addOpenHandler(new OpenHandler<DisclosurePanel>() {
#Override
public void onOpen(OpenEvent<DisclosurePanel> event) {
dPanel.setOpen(true);
}
});
dPanel.addCloseHandler(new CloseHandler<DisclosurePanel>() {
#Override
public void onClose(CloseEvent<DisclosurePanel> event) {
dPanel.setOpen(true);
}
});

GWT, disable autoclose MenuBar when clicking on MenuItem?

I want to if it is possible to disable the auto-close MenuBar when I click on a MenuItem?
I have several MenuItem that are like checkboxes, so I can check more than one MenuItem and don't want my menu close everytime I checked one.
Thanks.
I was facing same problem and I will share with you my solution:
1) Create new class MyMenuItemWithCheckBox that extends the MenuItem.
In the constructor set element ID to (forexample) menuItemWIthCheckBox + Unique text.
this.getElement().setId("menuItemWithCheckBox_" + menuItemLabel);
2) Create new class MyMenuBar that extends the MenuBar.
Override the onBrowserEvent method by following:
Override
public void onBrowserEvent(Event event) {
if (DOM.eventGetType(event) == Event.ONCLICK && getSelectedItem().getElement().getId().contains("CheckBox")) {
Scheduler.get().scheduleFinally(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
getSelectedItem().getScheduledCommand().execute();
}
});
event.stopPropagation();
} else {
super.onBrowserEvent(event);
}
}
Now scheduled command of MenuItem is always called, but in the case of your
menu checkBox item there is no close of a menubar.
I hope this help you, I spend more than day to create this solution. :-)
First, directly it's not possible because the popup-panel which displays the submenu is private in the MenuBar class.
Buuut, there is a way to do so ...
Simpley fetch the current MenuBar.java code out of googles code repository and include it in your eclipse gwt-project.
You don't have to change anything e.g. package deklaration or something. Just put your source in your project and it will simply replace the original MenuBar-class from the gwt-sdk during compilation (works also with hosted development mode).
Then you can simply set the property autoHide of the popup-Panel to false and the popup shouldn't disappear after clicking.
You can set hideOnClick to false on the menuItems
See here.