How to communicate between a RCP workbench toolbar and RCP views - java

I have a RCP application with some views and an ActionBarAdvisor that creates a toolbar for the application. The toolbar is initialized like this:
public class ApplicationActionBarAdvisor extends ActionBarAdvisor
...
protected void fillCoolBar(ICoolBarManager coolBar)
{
// Create new Toolbar
IToolBarManager toolbar = new ToolBarManager(coolBar.getStyle());
// Adds toolbar to perspective
coolBar.add(toolbar);
...
ActionContributionItem compareFilesCI = new ActionContributionItem(compareFiles);
compareFilesCI.setMode(ActionContributionItem.MODE_FORCE_TEXT);
toolbar.add(compareFilesCI);
...
}
The purpose of this toolbar item is to switch the color of the values of a JFace table. The user can switch the coloring in the table on or off by pressing the button.
But what is the best way to tell the table that coloring should be enabled/disabled? At the moment I've done it this way:
public class ActionCompareFiles extends Action implements ISelectionListener, ActionFactory.IWorkbenchAction
{
...
public void run()
{
// Check if the button is enabled. When it is enabled, comparison should be performed
try
{
// Get the label values view
final ViewFileValues labelViewer = (ViewFileValues) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getViewReferences()[3].getView(true);
// Refresh the view
labelViewer.setColoringValues(this.isChecked());
}
catch (Exception e)
{
System.out.println("Exception when searching the values view");
}
}
...
When pressing the button, I get the view that contains the table. Within this view class is a method 'SetColoringValues' that informs the label providers for the table columns that the button was pressed and updates the table.
This works but I'm not sure if it is the best solution...
My first idea was to simple add listeners to the button. After pressing the button, the listeners will be informed. But this seems not to work because I don't get the ActionBarAdvisor object, were the
toolbar was created. There seems to be no getter method for the toolbar that is part of the workbench window.
What is the best solution for this problem?

1) you should better use the Eclipse RCP commands framework (extension points *.commands, *.handlers, *.menu) instead of implementing this the way you do. It may look cumbersome at the first glance but in fact it is much more structured and straightforward.
2) the way you get an instance of the view is totally wrong: you rely upon the fact that the view has index of 3 in the page which is never warranted.

Related

How to switch back from one layout to the parent layout in the same activity

I'm creating a quiz app. Users are shown clues and have to guess the answer.
I have an activity with two layouts nested inside the "parent" constraint layout. The reason for this is that I needed a custom layout so I could pull rows from three columns from an SQLite database and display them in the app. These are the clues.
The top part of the activity is therefore this layout and the bottom part of the activity is another constraint layout that contains the buttons (refresh button to refresh the clues and check answer button) and the text view allowing the user to enter their text.
When I enter my activity, everything works fine. Clues are displayed and all buttons work.
When I press the refresh button (to refresh the clues), it refresh's the clue and then stops the buttons in the bottom layout from working, i.e I press them but nothing happens. My theory is that when I run the method that, it switches everything to the top layout and that stays (disabling the buttons in the bottom layout).
The bit of code that refresh's the clues, and therefore is causing the issue is this:
public void getPlayerHistory() { // Method used to get player history from DatabaseAccess.java,
// assign to list and place in the ListView
setContentView(R.layout.view_player_history); //the main layout everything is being displayed in
DatabaseAccess databaseAccess = DatabaseAccess.getInstance(getApplicationContext());
databaseAccess.open();
userList = new ArrayList<>();
Cursor data = databaseAccess.getListContents();
int numRows = data.getCount();
while (data.moveToNext()){
user = new User(data.getString(0), data.getString(1),
data.getString(2));
userList.add(user);
}
databaseAccess.close();
com.example.transfergame.ThreeClass adapter =
new com.example.transfergame.ThreeClass(this, R.layout.list_adapter_view, userList);
listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
Log.i("get player history", "playerHistoryFunction Run");
}
I think the issue is coming from this line
com.example.transfergame.ThreeClass adapter =
new com.example.transfergame.ThreeClass(this, R.layout.list_adapter_view, userList);
where I switch to my custom layout, but I'm not exactly sure what to code to then switch back to my parent layout.
Can someone point me in the right direction?
The issue actually came from
public void getPlayerHistory() {
setContentView(R.layout.view_player_history);
For some reason, setting this within this method, and not the onCreate() method was causing the issue. I have taken this out and put it in the onCreate() method and now everything runs fine.

Get slidingpanellayout events

I'm using sliding panels with my android app, but i need to get an event when the panel is up, is there a way listen to when it happens?
im using a sothree Sliding panel library
Looks like you are talking about umano/AndroidSlidingUpPanel. After briefly looking at the documentation/code you should be able to set a PanelSlideListener to your SlidingUpPanelLayout. They also provide a SimplePanelSlideListener which inserts no-ops for any functions you choose not to implement, which is probably what you will want to use.
For example inside of your Activity's onCreate you could do something like:
SlidingUpPanelLayout slidingPanel = (SlidingUpPanelLayout)findViewById(R.id.your_sliding_layout);
slidingPanel.setPanelSlideListener(new SimplePanelSlideListener() {
#Override
public void onPanelExpanded(View panel) {
// Insert your code here
}
});

How enable or disable correctly an Action

i have a little problem when i try to disable an Action of my Netbeans platform project. When the app starts, some Actions must be disabled, and i do that with this method:
CallableSystemAction.get(BuildProjectAction.class).setEnabled(FLAG);
It works, because the BuildProjectAction is disabled, but the corresponding items of the MenuBar and the Toolbar remains enabled until i click on one of it.
Only later that i have clicked on it, the comportament start to work correctly.
First question: Why?
If i want disable an Action, it's obvious that i want disable also the relative Icon in the Menu and in the Toolbar, so it must be automatic when i call Action.setEnabled(false).
It doesn't have sense that the Icons are not refreshed if i don't click on they.
Same problem if i try to use .getToolbarPresenter().setEnabled(false); and .getMenuPresenter().setEnabled(false);
For start the application with the icons disabled, I have tried to set the lazy attribute to FALSE and declare the image programmatically with the method setIcon(new ImageIcon(image)); that sets the same image for Menu and Toolbar.
And it works; there is only another problem: Menu and Toolbar have icons of different size (16x16 and 24x24).
It doesn't have sense that the if i set the icon with the #ActionRegistration(iconBase = "image.png") the correct icon is automatically selected, but if i use the method .setIcon(), it doesn't.
I have read some articles about Action, CookieAction, Lookup, but the only thing that i want is disable the graphic elements in the same moment when i disable the Action.
Second question: How i can do that?
This is an example of my Action.
#ActionID(
category = "Run",
id = "BuildProjectAction")
#ActionRegistration(
lazy = true,
iconBase = "images/icons/compile.png",
displayName = "#CTL_BuildProjectAction")
#ActionReferences({
#ActionReference(
path = "Menu/Run",
position = 3),
#ActionReference(path = "Toolbars/Run",
position = 3),
#ActionReference(
path = "Shortcuts",
name = "D-B")
})
#Messages("CTL_BuildProjectAction=Build Project")
public final class BuildProjectAction extends CallableSystemAction {
#Override
public void actionPerformed(ActionEvent e) {...}
#Override
public void performAction() {}
#Override
public String getName() {
return Bundle.CTL_BuildProjectAction();
}
#Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
Thanks
The easiest way to create an action that is disabled at startup is to use the platform’s New Action Wizard to create your action, and to create one that depends on a "context" -- this is, on finding a specific object in the global lookup. If no object is available in the lookup, as at startup, then the action will be disabled.
The menu and toolbar graphic elements are bundled together with your action via the annotations. This means that enabled/disabled state of your context-aware action will automatically affect the icons in the menu and toolbar as well.
This article by Geertjan Wielenga has a walkthrough on creating a context-aware action:
http://netbeans.dzone.com/how-to-make-context-sensitive-actions
When you want to enable your action, you will add the object on which the action depends into the global lookup, which will cause the action (and its graphic elements) to be enabled.
This entry in the platform’s Developer FAQ has some examples of how to add an object to the global context:
http://wiki.netbeans.org/DevFaqAddGlobalContext
If you need to create an action that depends on a more complex set of conditions there is some discussion, as well as a code sample illustrating how to do this, in this platform developer list thread:
http://forums.netbeans.org/ptopic55295.html
The grayed-out versions of the icons that are shown when your action is disabled are created automatically by the platform. You only have to provide the "normal" non-grayed-out images.
As for the icons of different sizes, it’s a matter of filename convention. If your annotation declares the icon with #ActionRegistration(iconBase = "image.png”), then you will provide a 16x16 image called “image.png” and a 24x24 version called “image24.png”. The platform will find and use the appropriate size in the menu and toolbar.

How could I know if the window is opened or not in Vaadin?

I use one layout in few cases. But when I show this layout in the window (com.vaadin.ui.Window) I have to hide one button otherwise layout stays unchanged. So I would like to know is the window opened or not at the moment. Is the any way to figure that out?
with getWindows you get all the windows of an UI. and with isAttached you will find out, if it is attached to the session (in a state where the user should see it)
I don't fully understand your question, but maybe this helps:
public class MyLayout extends VerticalLayout {
private Button myButton; // set it in the constructor
#Override
public void setParent(HasComponents parent) {
super.setParent(parent);
myButton.setVisible(!(parent instanceof Window)); // or recursively if need
}
}

Eclipse (XText) SelectionListener registration

I have implemented a view which shall register itself as listner for changes in the XText editor and related outline. To this end I am adding this line
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addSelectionListener(this);
in the createPartControl method of the view (which implements the ISelectionListener interface). In the selectionChanged method I therefore check whether the selection is a ITextSelection, the case in which it comes from the XTextEditor, or an IStructuredSelection, the case in which it come sfrom the Outline.
The problem is that, doing so, when I start Eclipse the outline is said to be "unavailable". If I click on the outline it is refreshed, the contents are shown and the listening view correctly updated.
What am I doing wrong and what should I do to avoid the initial "unavailability" of the outline?
I have been recently faced with this exact problem and have solved it by implementing IPartListener2 in the class that extends ViewPart then adding a part listener in the createPartcontrol method like this :
getSite().getWorkbenchWindow().getPartService().addPartListener(this);
Now by using something like this in your partOpened method (that has to be implemented before you can actually use the part listener you will get the view contents to be avaiable initially :
public void partOpened(IWorkbenchPartReference partRef) {
if(partRef.getPage().getActiveEditor() instanceof XtextEditor) {
somepart=partRef.getPage().getActiveEditor();
final XtextEditor editor = (XtextEditor)somepart;
final IXtextDocument document = editor.getDocument();
document.readOnly(new IUnitOfWork.Void<XtextResource>(){
public void process (XtextResource resource) throws Exception {
IParseResult parseResult = resource.getParseResult();
if(parseResult ==null)
return;
CompositeNode rootNode=(CompositeNode) parseResult.getRootNode();
LeafNode node = (LeafNode)NodeModelUtils.findLeafNodeAtOffset(rootNode, 0);
EObject object =NodeModelUtils.findActualSemanticObjectFor(node);
view.setInput(object);
}
});
}
}
this will make the view you're implementing get it's contents when you activate the XtextEditor (that is specific to your DSL).
In order to make the view change contents in real time as you change anything in the file active in the editor you should implement an IDocumentListener and override the DocumentChanged method. If you do this you won't be dependant on the SelectionListener anymore because the view should update automatically when something changes in your document
Hope this helps!

Categories