DragSourceListener never called while dragging and dropping file inside eclipse project explorer - eclipse

I am working on eclipse plugin that will allow a java bean to be dragged onto jsp file then on the drop event some code generators will be called.
I'm attempting to use the extension point "org.eclipse.ui.dropActions" but drag and drop listeners never get called .Is there any way to attach drag and drop listener to IFile object.
Am I on the right track with the DropActionDelegate?
Code:
DragListener
class DragListener implements DragSourceListener {
#Override
public void dragFinished(DragSourceEvent event) {
System.out.println("Finish");
}
#Override
public void dragSetData(DragSourceEvent event) {
PluginTransferData p;
p = new PluginTransferData (
"dream_action", // must be id of registered drop action
"some_data".getBytes() // may be of arbitrary type
);
event.data = p;
}
#Override
public void dragStart(DragSourceEvent event) {
// TODO Auto-generated method stub
System.out.println("Start");
}
}
DropActionDelegate
class DropActionDelegate implements IDropActionDelegate {
#Override
public boolean run(Object source, Object target) {
String Data= (String) target;
return true;
}
}
Plugin.xml
<extension point="org.eclipse.ui.dropActions">
<action
id="dream_action"
class="newdreamfileplugin.wizards.DropActionDelegate">
</action>
</extension>
Thanks.

Solved it.Finally i created my own navigator using org.eclipse.ui.navigator.navigatorContent extension which have a property dropAssistant.

Related

How to capture mouse click events from console in eclipse plugin

I'm developing an eclipse plugin. It writes some lines in a console. In order to select a line displayed in the console, I’m trying to capture mouse double click event from that console.
The console has been implemented by following this eclipse FAQ. MessageConsole or IconsoleView classes doesn‘t seem to provide a methode to add a listener with an SWT.MouseDoubleClick event.
Is there any way to capture a mouse event from a console and then read the selected line ?
The MessageConsole doesn't know anything about how the data is displayed, it is the TextConsoleViewer that deals with that.
To access the console viewer you need to use a custom message console - extending MessageConsole or TextConsole and overriding createPage to create your own console page extending TextConsolePage.
The console page needs to override the createViewer method to create your own text console viewer extending TextConsoleViewer.
In the viewer you can override the mouseDoubleClick method to receive the double clicks.
For an example see the Eclipse JDT JavaStackTraceConsole, JavaStackTraceConsolePage, and JavaStackTraceConsoleViewer classes.
public class JavaStackTraceConsole extends TextConsole {
...
#Override
public IPageBookViewPage createPage(IConsoleView view) {
return new JavaStackTraceConsolePage(this, view);
}
}
public class JavaStackTraceConsolePage extends TextConsolePage {
...
#Override
protected TextConsoleViewer createViewer(Composite parent) {
return new JavaStackTraceConsoleViewer(parent, (JavaStackTraceConsole) getConsole());
}
}
public class JavaStackTraceConsoleViewer extends TextConsoleViewer {
...
}
Thank you, it works fine. I just had to managed the mouse event in another way because overriding the mouseDoubleClick method didn’t work. Here is my code :
public class MyTextConsoleViewer extends TextConsoleViewer {
public MyTextConsoleViewer(Composite parent, MyMessageConsole console) {
super(parent, console);
StyledText styledText = getTextWidget();
MouseListener listener = new MouseListener() {
#Override
public void mouseUp(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDown(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDoubleClick(MouseEvent event) {
// TODO Auto-generated method stub
IDocument document = console.getDocument();
try {
int currentLine = document.getLineOfOffset(styledText.getOffsetAtLocation(new Point (event.x, event.y)));
IRegion lineInfo = document.getLineInformation(currentLine);
System.out.println(document.get(lineInfo.getOffset(), lineInfo.getLength()));
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
styledText.addMouseListener(listener );
// TODO Auto-generated constructor stub
}
public MyTextConsoleViewer(Composite parent, TextConsole console,
IScrollLockStateProvider scrollLockStateProvider) {
super(parent, console, scrollLockStateProvider);
// TODO Auto-generated constructor stub
}
#Override
public void mouseDoubleClick(MouseEvent e) {
System.out.println("This even doesn't work!");
}
}

Catch closing event of a part (Eclipse e4 RCP)

I'm currently working on a eclipse e4 RCP application and I have a part that serves as a job manager where the user can see all active jobs and their progresses, like one in eclipse. The problem is now that the user can open the progress part by double clicking in the toolbar and he should also be able to close the progress part whenever he wants, but instead of disposing the part I want to just make it invisible.
I thought at first this shouldn't be a problem because I can set the part to be not visible, but the problem is how to catch the closing event and process it by my way. Is there any event, interfaces or listeners I can implement to catch the closing event and prevent the part from getting disposed?
You can implement a CustomSaveHandler and replace the Default Eclipse Save Handler with a Processor. In that SaveHandler you can control if the Part shoud get closed or not. So you could do not close it and make it invisible.
ExampleCode:
public class ReplaceSaveHandlerProcessor {
#Named("your.id.to.window")
#Inject
MWindow window;
#Inject
IEventBroker eventBroker;
#Execute
void installIntoContext() {
eventBroker.subscribe(UIEvents.Context.TOPIC_CONTEXT, new EventHandler() {
#Override
public void handleEvent(final Event event) {
if (UIEvents.isSET(event)) {
if (window.equals(event.getProperty("ChangedElement")) && (window.getContext() != null)) {
window.getContext().runAndTrack(new RunAndTrack() {
private final ISaveHandler saveHandler = new CustomSaveHandler();
#Override
public boolean changed(final IEclipseContext context) {
Object getSaveHandlerValue = context.get(ISaveHandler.class);
if (!saveHandler.equals(getSaveHandlerValue)) { // prevents endless loop
ContextInjectionFactory.inject(saveHandler, window.getContext());
context.set(ISaveHandler.class, saveHandler);
}
return true; // ture keeps tracking and the saveHandler as the only opportunity
}
});
}
}
}
});
}
}
You have to define a Extention for ExtentionPoint org.eclipse.e4.workbench.model
With Your ReplaceSaveHandlerProcessor. (You have to declare the window id as "element" in this extention. (Added Screenshot: )
The CustomSaveHandler have to implement the ISaveHandler interface. In its Methods ypu can say if the Part should realy be closed.
public class CustomSaveHandler implements ISaveHandler {
#Override
public boolean save(MPart dirtyPart, boolean confirm) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm) {
// TODO Auto-generated method stub
return false;
}
#Override
public Save promptToSave(MPart dirtyPart) {
// TODO Auto-generated method stub
return null;
}
#Override
public Save[] promptToSave(Collection<MPart> dirtyParts) {
// TODO Auto-generated method stub
return null;
}
}

Updating Eclipse JFace Treeviewer when model changes?

I am developing a RCP application with a TreeViewer. While there are good number of articles to explain how to add editing support to the Viewer (and how changes in view are updated in the model), I don't find much for updating the Treeview when the underlaying model changes. my question in short:
TreeView ----> Model updation ------ there are lots of examples
Model ----> Treeview updation ----- this is my question
Edit:
This is what I tried and it works. comments please
viewer.getTree().addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if(e.keyCode==SWT.F3){
System.out.println("F3 pressed... new element will be added");
TreeParent root = (TreeParent) viewer.getInput();
TreeParent activityRoot = (TreeParent) root.getChildren()[0];
activityRoot.addChild(new TreeObject("NEW_ACTIVITY"));
//viewer.update(root, null);
viewer.refresh();
}
}
});
The data model is provided by your content provider, TreeViewer does not provide any means of changing this data - you must do that it your own code. When you have changed to model you can use the following methods to tell the TreeViewer about the change:
If you have just changed what needs to be shown for a single item in the tree use
TreeViewer.update(object, null);
to get that item in the tree updated. There is also an array version of this to update multiple objects.
If you have added or removed objects in the tree use
TreeViewer.refresh();
to rebuild the whole tree or
TreeViewer.refresh(object);
to refresh the part of the tree start at object.
To tell the tree about adding and removing objects there are
TreeViewer.add(parent, object);
TreeViewer.remove(object);
there are also array variants of these.
To help the TreeViewer find the objects call
TreeViewer.setUseHashlookup(true);
(must be called before TreeViewer.setInput). Since this uses a hash table the objects should have sensible hashCode and equals methods. You can also use TreeViewer.setComparer to specify a different class to do the hash code and comparison.
Based on the comments in this thread,one of the eclipse corner articles on using TreeViewer and few experimenting I had created a working model.
Here are the steps:
Create a listener interface like the following
public interface TreeModelListener extends EventListener {
public void onDelete(TreeObject obj);
}
Let the tree Content provider to add listeners to each tree model item and implement this interface like below
public class TreeContentProvider implements IStructuredContentProvider,ITreeContentProvider,TreeModelListener {
TreeViewer tv;
public TreeContentProvider(TreeViewer tv){
this.tv=tv;
}
int cnt=0;
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
cnt ++;
System.out.println("inputChanged() called "+oldInput+" new: "+newInput);
if(newInput!=null){
((TreeParent)newInput).setListener(this);
TreeObject []items = ((TreeParent)newInput).getChildren();
for(TreeObject obj : items){
if(obj instanceof TreeParent){
((TreeParent) obj).setListener(this);
}
}
}
}
....
#Override
public void onDelete(TreeObject obj) {
System.out.println("Delete of "+obj+" handled by content handler ");
TreeParent parent = obj.getParent();
if(parent.getChildren().length<=1){
return;
}
parent.removeChild(obj);
this.tv.refresh();
}
}
Add a method to the TreeModel class as below . And obviously TreeParent class should have an ArrayList of listeners that is being used in #1 above
public void fireChildDelete(final TreeObject obj){
if(this.listener!=null){
new Runnable(){
#Override
public void run() {
System.out.println("New thread spawned with ID "+Thread.currentThread().getId());
listener.onDelete(obj);
}
}.run();
}
}
Finally add KeyListener to the TreeViewer Object to handle Delete key as below:
tv.getTree().addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if(e.keyCode==SWT.F3){
System.out.println("F3 pressed... new element will be added");
TreeParent root = (TreeParent) tv.getInput();
TreeParent activityRoot = (TreeParent) root.getChildren()[0];
activityRoot.addChild(new TreeObject("NEW_ACTIVITY"));
//viewer.update(root, null);
tv.refresh();
}
if(e.keyCode==SWT.DEL){
System.out.println("DEL key pressed... element will be deleted "+((Tree)e.getSource()).getSelection().length);
if(((Tree)e.getSource()).getSelection().length>0){
final IStructuredSelection selection = (IStructuredSelection) tv
.getSelection();
System.out.println("DEL#2 key pressed... element will be deleted "+selection.getFirstElement().getClass());
TreeParent parent = ((TreeObject)selection.getFirstElement()).getParent();
parent.fireChildDelete((TreeObject) selection.getFirstElement());
//tv.remove(selection.getFirstElement());
//viewer.update(viewer.getInput(),null);
//tv.refresh();
}
}
}
});

Eclipse plugin - is there any editable TreeSelection class

I am looking for a solution to make this tree selection editable in the package explorer view itself.
the idea
for example- if we click rename on any class in package explorer, it will prompt a new window to rename. This functionality is same for any class that implement TreeSelection Class.
But the Solution i am looking for is - when rename is invoked, the rename option is shown at the tree itself (like we have in Windows Explorer view)
any suggestion on how to attain this behavior on eclipse.
You don't need to have some special editable selection, you just want to make the tree editable. For this you use EditingSupport, like this (adapted from http://www.vogella.com/articles/EclipseJFaceTableAdvanced/article.html#jfacetable_editor):
public class NameEditingSupport extends EditingSupport {
private final TreeViewer viewer;
public FirstNameEditingSupport(TreeViewer viewer) {
super(viewer);
this.viewer = viewer;
}
#Override
protected CellEditor getCellEditor(Object element) {
return new TextCellEditor(viewer.getTree());
}
#Override
protected boolean canEdit(Object element) {
return true;
}
#Override
protected Object getValue(Object element) {
// return the name
}
#Override
protected void setValue(Object element, Object value) {
// update the name of your object
viewer.update(element, null);
}
}
// in the code creating the tree
treeViewer.setEditingSupport(new NameEditingSupport(treeViewer));

Drag and Drop in GWT using gwt dnd

I have been really struggling to get Drag and Drop working in GWT. Last 3 days, I was trying to create a basic drag and drop application and failed. Currently I can drag it around, but I am unable to drop to any location.
How can we solve it? Do we need to modify onDragEnd - I am under the impression that unless I specifically have to do something, I dont have to? I am quite confused.
Also, how do I limit the drop to any single area? I do understand that we can do it using DropController. But I have defined the panels using UiBinder, so how do I get that panel back to link in the DropController? i.e. RootPanel.get() gives me the basic root panel and not the actual panel I want. I tried RootPanel.get("field-id"), but that is showing null even if that id is available. What am I doing wrong?
The code I have written is as follows:
public class TestPanel extends Composite implements
DragHandler, HasMouseDownHandlers, HasMouseUpHandlers, HasMouseMoveHandlers, HasMouseOutHandlers {
interface Binder extends UiBinder<Widget, TestPanel> { }
private static final Binder binder = GWT.create(Binder.class);
#UiField AbsolutePanel absolutePanel;
private PickupDragController TestDragController;
private Image img = new Image("./testicon.png");
public TestPanel(){
initWidget(binder.createAndBindUi(this));
absolutePanel.add(img);
TestDragController = new PickupDragController(RootPanel.get(), false);
AbsolutePositionDropController dropController = new AbsolutePositionDropController(
RootPanel.get());
TestDragController.registerDropController(dropController);
TestDragController.addDragHandler(this);
TestDragController.makeDraggable(this, getDragHandle());
}
private Widget getDragHandle() {
return img;
}
#Override
public void onDragEnd(DragEndEvent event) { }
#Override
public void onDragStart(DragStartEvent event) { }
#Override
public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException { }
#Override
public void onPreviewDragStart(DragStartEvent event) throws VetoDragException { }
#Override
public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
return addDomHandler(handler, MouseDownEvent.getType());
}
#Override
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
return addDomHandler(handler, MouseUpEvent.getType());
}
#Override
public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
return addDomHandler(handler, MouseMoveEvent.getType());
}
#Override
public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
return addDomHandler(handler, MouseOutEvent.getType());
}
}
and the testpanel uibinder looks like the following:
<g:AbsolutePanel ui:field="absolutePanel" styleName="{style.panel}">
</g:AbsolutePanel>
If somebody can help me out, I will be very much obliged.
K
P.S: To explain more: I was able to solve the first question by updating onDragEnd as the following:
#Override
public void onDragEnd(DragEndEvent event) {
DragContext context = event.getContext();
RootPanel.get().add(context.draggable, context.desiredDraggableX, context.desiredDraggableY);
}
but, I am not sure whether this is the correct solution - since I think I should not be doing the positioning myself.
If you're new to GWT dnd, why don't you try the working demo ?
There is a lot of examples and all the source code is available.
(And no, you're not supposed to do the positionning yourself)
You have to add a DragOverHandler on the drop target(s): even if it does nothing, it defines the component as a drop target.
Of course, you still need to define the DropHandler too on this component (and optionally, DragEnterHandler and DragLeaveHandler for visual feedback, in general).
The DragEndHandler is called even if the target isn't reached (drag abandoned in a non-drop area), it is used to change the state of the dragged object, you might need to set a way for the DropHandler to communicate success on dropping to the DragEndHandler (shared variable, EventBus, etc.).