I am trying to create my own problem view.
I found the following tutorial and all works fine.
But is there any possibility to add an own DoubleClickListener or something like that?
I want to react on user actions, which are executed on the list.
Thanks for any advices.
Here is what I would do:
by overriding public void createPartControl(final Composite parent) you will have the parent composite. By calling parent.getChildren() you can iterate over the available Controls. ExtendedMarkersView "default" control is MarkersTreeViewer which is a treeViewer, so the control would be a tree. You have the tree, you can add any listener you want, here is the snippet:
#Override
public void createPartControl(final Composite parent) {
super.createPartControl(parent);
for (final Control control : parent.getChildren()) {
if (!(control instanceof Tree)) {
continue;
}
tree = (Tree) control;
final Listener[] listeners = tree.getListeners(SWT.DefaultSelection);
if (listeners != null) {
for (final Listener listener : listeners) {
tree.removeListener(SWT.DefaultSelection, listener);
}
}
tree.addMouseListener(new MouseAdapter() {
#Override
public void mouseDoubleClick(final MouseEvent e) {
if (e.widget instanceof Tree) {
final Tree tree = (Tree) e.widget;
// do whatever you want
}
}
});
}
}
I found a solution, not the best one, but an acceptable way.
I use the SelectionService in my ViewPart and register a new SelectionListener.
My solution only accepts a selection in the problem view, perhaps there is a better way to differ the events.
site.getWorkbenchWindow().getSelectionService().addSelectionListener(new ISelectionListener() {
#Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
IStructuredSelection s = (IStructuredSelection) selection;
if (s.getFirstElement() instanceof MarkerItem) {
MarkerItem marker = (MarkerItem) s.getFirstElement();
if (marker != null && marker.getMarker() != null) {
IMarker iMarker = marker.getMarker();
// More Code here ...
}
}
}
});
Related
I am currently looking for content assist feature in Nattable TextCellEditor.I have found the way to attach the ContentProposalAdapter and IContentProposalProvider by extending the Nattable TextCellEditor. but ,The selected value from the proposed list is not updating in the text control.
Snippet :
#Override
protected Text createEditorControl(final Composite parent, final int Style) {
this.textControl = super.createEditorControl(parent, style);
contentProposalAdapter =
new ContentProposalAdapter(this.textControl, new TextContentAdapter(), contentProposalProvider, keyStroke,
null);
contentProposalAdapter.addContentProposalListener(new IContentProposalListener() {
#Override
public void proposalAccepted(IContentProposal proposal) {
System.out.println(proposal.getContent());
}
});
}
The problem you have is the internal FocusListener that is triggered while selecting a value in the popup. To add the support you also need to override the internal FocusListener with a listener that doesn't fire if the content proposal popup is open.
An example would be to add a boolean flag that indicates that the popup is open and add a listener that sets the flag accordingly.
private boolean popupOpen = false;
...
contentProposalAdapter.addContentProposalListener(new IContentProposalListener2() {
#Override
public void proposalPopupClosed(ContentProposalAdapter adapter) {
this.popupOpen = false;
}
#Override
public void proposalPopupOpened(ContentProposalAdapter adapter) {
this.popupOpen = true;
}
});
And then implement and set a FocusListener in the constructor that takes care of that flag.
this.focusListener = new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
if (!TextCellEditor.this.popupOpen) {
if (!commit(MoveDirectionEnum.NONE, true)) {
if (e.widget instanceof Control && !e.widget.isDisposed()) {
((Control) e.widget).forceFocus();
}
} else {
if (!TextCellEditor.this.parent.isDisposed())
TextCellEditor.this.parent.forceFocus();
}
}
}
};
In case the value should be immediately committed after it is selected, you need to add a listener that performs the commit after selection.
contentProposalAdapter.addContentProposalListener(new IContentProposalListener() {
#Override
public void proposalAccepted(IContentProposal proposal) {
commit(MoveDirectionEnum.NONE);
}
});
Unfortunately the AbstractCellEditor#InlineFocusListener is private and can therefore not be extended.
Feel free to file an enhancement ticket for NatTable to introduce the ability to easily add content proposals to a text cell editor.
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=NatTable
I am trying to Update my Custom ListView which is fed by two String Arrays:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getStringArray(ARG_PARAM1);
mParam2 = getArguments().getStringArray(ARG_PARAM2);
}
setupListView();
}
private void setupListView() {
listItemList = new ArrayList();
if (mParam1 != null && mParam2 != null && mParam1.length == mParam2.length) {
for (int i = 0; i < mParam1.length; i++) {
listItemList.add(new MyListItem(mParam1[i], (mParam2[i]).substring(0, 75) + "..."));
}
} else {
listItemList.add(new MyListItem("Loading...", "Swipe Down for Update"));
}
mAdapter = new MyListAdapter(getActivity(), listItemList);
}
mParam1 and mParam2 are Values which are fetched by an XML parser (IntentService) class in the MainActivity which i can show if needed.
Now, if i am to fast, and the mPara1 and mPara2 is empty there won´t be any ListView shown. Now i want to solve this by some AsyncTask or IntentService whatever is useful. I tried AsyncTask, which didn´t work at all. I tried notifyDataSetChanged() which didn´t work too...
Now, how could i solve this....
Using AsyncTask i have the problem that i don´t know how to passt the two Arrays to publishProgress() correctly
THis is how my AsyncTask looks like:
class UpdateListView extends AsyncTask<Void, String, Void> {
private MyListAdapter adapter;
private ArrayList listItemList;
#Override
protected void onPreExecute() {
adapter = (MyListAdapter) mListView.getAdapter();
}
#Override
protected Void doInBackground(Void... params) {
for (String item1 : mParam1) {
publishProgress(item1);
}
return null;
}
#Override
protected void onProgressUpdate(String... values) {
adapter.add(new MyListItem(values[0], values[1]));
}
#Override
protected void onPostExecute(Void result) {
Log.d("onPostExecute", "Added successfully");
}
}
Okay solved it...My Fragments are running in same Activity where the Data is loaded in, so i just created getter and setter in MainActivity and access them in the needed Fragment via
String[] titles =(MainActivity) getActivity()).getTitlesArray();
String[] text=(MainActivity) getActivity()).getTextArray();
Whatever i do trying setting Bundle with
bundle.putStringArray(TITLES,titles);
doesn´t work. Should work using parceable/serializable class but didn´t try...
I am creating an Eclipse RCP application with multiple views. One of my views is a multi-page editor view. Each of those pages has a a master/details block. I need to register all of those TableViewers as selection providers for my other view to listen to.
After much research online, I came across this article about multiple selection providers in a single view. I followed the instructions to create this selection provider for multiple viewers.
class MyMultipleSelectionProvider implements ISelectionProvider {
private final ListenerList selectionListeners = new ListenerList();
private ISelectionProvider delegate;
private final ISelectionChangedListener selectionListener = new ISelectionChangedListener() {
#Override
public void selectionChanged(final SelectionChangedEvent event) {
if (event.getSelectionProvider() == AdaptabilityProfileSelectionProvider.this.delegate) {
fireSelectionChanged( event.getSelection() );
}
}
};
/**
* Sets a new selection provider to delegate to. Selection listeners
* registered with the previous delegate are removed before.
*
* #param newDelegate new selection provider
*/
public void setSelectionProviderDelegate(final ISelectionProvider newDelegate) {
if (this.delegate == newDelegate) {
return;
}
if (this.delegate != null) {
this.delegate.removeSelectionChangedListener(this.selectionListener);
}
this.delegate = newDelegate;
if (newDelegate != null) {
newDelegate.addSelectionChangedListener(this.selectionListener);
fireSelectionChanged(newDelegate.getSelection());
}
}
#Override
public void addSelectionChangedListener(final ISelectionChangedListener listener) {
this.selectionListeners.add(listener);
}
#Override
public ISelection getSelection() {
return this.delegate == null ? null : this.delegate.getSelection();
}
#Override
public void removeSelectionChangedListener(final ISelectionChangedListener listener) {
this.selectionListeners.remove(listener);
}
#Override
public void setSelection(final ISelection selection) {
if (this.delegate != null) {
this.delegate.setSelection(selection);
}
}
protected void fireSelectionChanged(final ISelection selection) {
fireSelectionChanged(this.selectionListeners, selection);
}
private void fireSelectionChanged(final ListenerList list, final ISelection selection) {
final SelectionChangedEvent event = new SelectionChangedEvent(this.delegate, selection);
final Object[] listeners = list.getListeners();
for (int i = 0; i < listeners.length; i++) {
final ISelectionChangedListener listener = (ISelectionChangedListener) listeners[i];
listener.selectionChanged(event);
}
}
}
I added a focusListener on all of the edior's viewers so they become the delegate:
tree.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(final FocusEvent e) {
editor.getSelectionProvider().setSelectionProviderDelegate(MyEditorPage.this.treeViewer);
}
});
And I registered this as the selection provider for my editor:
site.setSelectionProvider( this.selectionProvider );
Then, within my view that needs to hear about the selection, I registered a selection listener for this editor:
getSite().getPage().addSelectionListener(MyEditor.ID, this.selectionListener);
When I run the application, I see that the delegate is being changed and the selection events are being fired. However, the listener list is empty.
I am never calling addSelectionChangeListener() directly. I was under the impression that that was what the selection service is for. Am I wrong? Should I be calling it? If so, when? If not, who is supposed to be adding the listener, and why isn't it happening?
If your code is based on FormEditor (or MultiPageEditorPart) then the selection provider is set to MultiPageSelectionProvider at the end of the init method. This may be overriding your site.setSelectionProvider call.
Using:
#Override
public void init(IEditorSite site, IEditorInput input)
throws PartInitException {
super.init(site, input);
site.setSelectionProvider(this.selectionProvider);
}
should make sure your provider is the one used.
I am Trying to create Eclipse Plugin which has a composite with two TreeViewer side by side. On click of each TreeViewer content Eclipse property view should give appropriate information. Now I wanted to set Selection provider for both of this treeviewer hence I used
setSelectionProvider(treeViewer1)
setSelectionProvider(treeviewer2)
But only the second added treeviewer get set since the first one is overwritten. I am intiating this two treeviewer from class Queue.java. Hence I implemented the interface ISelectionProvider over Queue.java as below:
public void addSelectionChangedListener(ISelectionChangedListener listener)
{
selectionChangedListeners.add(listener);
}
public void
removeSelectionChangedListener(ISelectionChangedListener listener)
{
selectionChangedListeners.remove(listener);
}
private void fireSelectionChanged(final SelectionChangedEvent event)
{
Object[] listeners = selectionChangedListeners.getListeners();
for (int i = 0; i < listeners.length; ++i)
{
final ISelectionChangedListener l =
(ISelectionChangedListener) listeners[i];
Platform.run(new SafeRunnable()
{
public void run()
{
l.selectionChanged(event);
}
#Override
public void handleException(Throwable e)
{
removeSelectionChangedListener(l);
}
});
}
}
public void setSelection(ISelection selection)
{
fireSelectionChanged(new SelectionChangedEvent(this, selection));
}
public ISelection getSelection()
{
ArrayList<Object> list = new ArrayList<Object>();
Object o = getProperties();
if (o instanceof IPropertySource)
list.add(o);
return new StructuredSelection(list);
}
Can anyone help me how to resolve this issue. I will be grateful. thanks in advance. Tor.
Your view would have to write a selection provider wrapper or mediator that would delegate to the viewer that currently had focus. Then your view would set it up something like this:
SelectionProviderWrapper wrapper = new SelectionProviderWrapper();
wrapper.addViewer(treeViewer1);
wrapper.addViewer(treeViewer2);
getSite().setSelectionProvider(wrapper);
I would check out org.eclipse.jdt.internal.ui.viewsupport.SelectionProviderMediator for an example of a selection provider for multiple JFace viewers.
I can't understand that part, neither trying the showcase examples.
I'm using an extension of AsyncDataProvider to bind my tree to RPC service. Here's my method:
public <T> NodeInfo<?> getNodeInfo(T value) {
/*
if (value instanceof Categoria) {
dataProvider.setCurrentParent((Categoria)value);
}
*/
return new DefaultNodeInfo<Categoria>(dataProvider, new CategoriaCell());
}
"currentParent" is my stuff: except for (null => root) values, I set the parent to pass via RPC to my service. Actually, in my widget code:
dataProvider = new CategorieTreeDataProvider() {
#Override
protected void onRangeChanged(HasData<Categoria> display) {
updateTree(getCurrentParent());
}
};
private void updateTree(Categoria categoria) {
rpcService.getCategorie(categoria, new AsyncCallback<Categoria[]>() {
#Override
public void onSuccess(Categoria[] result) {
dataProvider.updateRowCount(result.length, true);
dataProvider.updateRowData(0, Arrays.asList(result));
}
#Override
public void onFailure(Throwable caught) {
Window.alert(caught.toString());
}
});
}
My rpc-server code, however, is working as expected:
#Override
public Categoria[] getCategorie(Categoria parent) {
List<Categoria> categoryList = categorieDao.listByProperty("parent", parent);
for (Categoria c : categoryList) {
if (categorieDao.listByProperty("parent", c).size() == 0) {
c.setLeaf(true);
}
}
return categoryList.toArray(new Categoria[0]);
}
**Then I add some data to my Categories: 'GrandFather', 'Father' and 'Son'.
Unfortunately, after loading my widget, I see:
The grandfather correctly, with his "+" how expected;
Then I click it and...
The grandfather disappear and I see 'Father' with his '+'
same for father -> son
I suspect the bug is in updateRowCount / updateRowData usage.**
Any ideas?
The getNodeInfo is called whenever you open a node so you have to create distinct DataProvider for each of the nodes's childs.
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
return new DefaultNodeInfo<Category>(dataProvider, new CategoriaCell());
}
else if (value instanceof Categoria) {
Category category = (Category)value;
return new DefaultNodeInfo<Grandfather>(new ListDataProvider<Grandfather>(category.getGrandFathers()),new GrandFatherCell());
}
else if (value instanceof Grandfather) {
Grandfather grandfather = (Grandfather)value;
return new DefaultNodeInfo<Father>(new ListDataProvider<Father>(granfather.getFathers()),new FatherCell());
}
else if (value instanceof Father) {
//same as above but with fathers.
}
}
The category.getGrandFathers() function can for example do a RPC request to the server or just return the list if you retrieve everything in one RPC request.
UPDATE based on comment:
So in case you have only one class and want to achieve a dynamic CellTree (number of levels are not pre-determined) you could take following approach.
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
return new DefaultNodeInfo<Category>(dataProvider, new CategoriaCell());
}
else {
Category category = (Category)value;
return new DefaultNodeInfo<Category>(new ListDataProvider<Category>(category.getSubCategories()),new CategoryCell());
}
}
category.getSubCategories() is either an RPC call which retrieves the subcategories for the current category or if the Category class is a linked list type datastructure it could just return the list of subcategories.
Each data provider updates a given "list" (child nodes of a given parent node), so you have to use a distinct data provider instance for each parent node, or your calls will update some random list.