Active perspective is null if a view is detached - java

If I right click and detach a view, modelService.getActivePerspective(window) starts returning null. This means that resetting the perspective doesn't work correctly.
If a view isn't detached it works correctly. I'm thinking that as a new window is open it is passing a different window that doesn't contain the perspective.
Example
public class ResetPerspectiveHandler {
#Execute
public static void resetPerspective(final MApplication app, final EPartService partService,
final EModelService modelService, final MWindow window) {
// Prints null
System.out.println(modelService.getActivePerspective(window));
PerspectiveSnippetsCopier.resetPerspective(modelService, partService, app, window,
modelService.getActivePerspective(window).getElementId());
}
}
What could be causing this?

The code for getActivePerspective is:
public MPerspective getActivePerspective(MWindow window) {
List<MPerspectiveStack> pStacks = findElements(window, null, MPerspectiveStack.class);
if (pStacks.size() == 1) {
MPerspective perspective = pStacks.get(0).getSelectedElement();
return perspective;
}
return null;
}
So it expects to find a MPerspectiveStack in the given window, presumbly the detached window does not have this.
You could try finding the main window in the app rather than using the current window.
MWindow mainWindow = (MWindow)modelService.find("main window id", app);

Related

Vaadin SliderPanel not displaying

I'm using the Vaadin add-on SliderPanel (https://vaadin.com/directory#!addon/sliderpanel) in my project and am having a very hard time making it go away and reappear on the correct view. When I load the application and log in, it correctly takes me to the correct class/page, 'Dashboard', with no SliderPanel. When I navigate to any other class/page which is supposed to re-display the SliderPanel, it does not appear as expected. In order for me to get it to show, I have to resize the window. Same thing happens when I resize the window then go back to the 'Dashboard' page...I have to resize the window and the SliderPanel tab goes away. How can I get the SliderPanel tab to update itself when changing views with the navigator?
In my UI I have #push() annotated above the main class.
#Push()
public class EvoltwebUI extends UI implements ClickListener {...}
Inside the class I have these annotations and servlet class:
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = EvoltwebUI.class, widgetset = "com.evolt.evoltweb.widgetset.EvoltwebWidgetset")
public static class Servlet extends VaadinServlet {
}
I've registered the views like this:
private void registerViews() {
navigator.addView("dashboard", DashboardViewImpl.class);
navigator.addView("groups", GroupsViewImpl.class);
navigator.addView("research", ResearchViewImpl.class);
navigator.addView("reporting", ReportsViewImpl.class);
navigator.addView("execution", AdhocExecView.class);
navigator.addView("tcreview", TestCaseReviewView.class);
navigator.addView("toolbox", ToolboxView.class);
}
The 'enter' method on each view/class looks like this:
#Override
public void enter(ViewChangeEvent event) {
presenter.onViewEnter(event.getParameters());
generateFields();
ProgressPanel.setViewName("Test Case Review - Please load a group from the Test Group Explorer Slider Panel on the left.");
evoltWebUI.getTreeViewSlider().defaultTab();
}
I've tried using these, but I am having the same type of issue to where it will not come back if setVisible is false. :
leftTreeViewSlider.setVisible(true);
leftTreeViewSlider.setVisible(false);
I've also tried extending SliderPanel to access the actual size of the tab to shrink it, but when setting it back to the normal size I have to resize the window to get it back.
import org.vaadin.sliderpanel.SliderPanel;
import org.vaadin.sliderpanel.SliderPanelBuilder;
import com.vaadin.ui.Component;
public class SliderPanelMod extends SliderPanel{
public SliderPanelMod(SliderPanelBuilder builder) {
super(builder);
}
public void resizeTab(int t) {
this.getState().tabSize = t;
}
public void defaultTab() {
resizeTab(40);
}
}
Does anyone have any ideas what would be causing this?

JavaFX setGraphic() not displaying icon in MenuItem

I need an icon for my MenuItem's.
This is like a "worker class" to get the ImageView of the icon :
public class IconFactory {
private static ImageView HLP_BOOK_JFX;
public enum ICONS {
BASCET_REMOVE, BASCET_PUT, SAVE, OPEN, ARROW_RIGHT, ARROW_LEFT, ARROW_UP, ARROW_DOWN, CLOCK, ANALOG_SIGNAL, DIGITAL_SIGNAL, REFRESH, GREEN_PLUS, NETWORK, OK, CANCEL, RIGHT_NAV2, LEFT_NAV2, PLAY, PAUSE, LIST_ADD, PAGE_FIND, SET_PARAM, DOWNLOAD, UPLOAD, LOG_FILE, WARNING, INFO, LOG_DIAG, DATA_TRANS, TREE, FILTER, SEARCH, PARAM, ERASE, RESETDEF, RESETDEF2, DEBUG_BUG, INTERNATIONAL, CLOSE, HLP_BOOK
}
public static ImageView getImage(ICONS en) {
switch (en) {
case HLP_BOOK:
if (HLP_BOOK_JFX == null)
HLP_BOOK_JFX = new ImageView(new Image(IconFactory.class.getResourceAsStream("help_book.png")));
return HLP_BOOK_JFX;
}
return null;
}
When I use myMenuItem.setGraphic(IconFactory.getImage(ICONS.HLP_BOOK)) for a single menu item it works perfectly.
But then, when I want to generate two menus in a loop and set the same graphic, one MenuItem has no icon displayed. (the first one in loop in the code below).
My code:
while (keys.hasMoreElements()) {
// that will do 2 loops, do not care about how
MenuItem subMenuHelp = new MenuItem("MenuItem");
subMenuHelp.setGraphic(IconFactory.getImage(ICONS.HLP_BOOK));
subMenuHelp.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
// do not care
openHelpFile(link);
}
});
System.out.println(((ImageView) subMenuHelp.getGraphic()).toString());
myMenu.getItems().add(subMenuHelp);
}
As you can see, I added a System.out.println to see if a graphic was set for the current item.
Result in console : both lines (MenuItem) with the same ImageView:
ImageView#79814766[styleClass=image-view]
ImageView#79814766[styleClass=image-view]
I did exactly the same in Swing (but with Icons and .setIcons() function) and it worked very well. I've also looked for a "repaint" function to force displaying but no way.
Hope you can help me!
This is because the same Node cannot be attached to the scene-graph multiple times and - as you even state - you are adding the same ImageView object.
From the documentation of Node:
If a program adds a child node to a Parent (including Group, Region,
etc) and that node is already a child of a different Parent or the
root of a Scene, the node is automatically (and silently) removed from
its former parent.
The solution is to modify getImage method of IconFactory to return a new ImageView instance on each call or to return Image instances rather than ImageView instances (the second one fits better to the name "IconFactory" I think).
You could store the Image instance instead of storing the ImageView to avoid re-loading the Image itself. You could check this question as reference: Reusing same ImageView multiple times in the same scene on JavaFX
A possible update on IconFactory:
public class IconFactory {
private static HashMap<ICON, Image> images = new HashMap<ICON, Image>();
public enum ICON {
BASCET_REMOVE, BASCET_PUT, SAVE, OPEN, ARROW_RIGHT, ARROW_LEFT, ARROW_UP, ARROW_DOWN, CLOCK, ANALOG_SIGNAL, DIGITAL_SIGNAL, REFRESH, GREEN_PLUS, NETWORK, OK, CANCEL, RIGHT_NAV2, LEFT_NAV2, PLAY, PAUSE, LIST_ADD, PAGE_FIND, SET_PARAM, DOWNLOAD, UPLOAD, LOG_FILE, WARNING, INFO, LOG_DIAG, DATA_TRANS, TREE, FILTER, SEARCH, PARAM, ERASE, RESETDEF, RESETDEF2, DEBUG_BUG, INTERNATIONAL, CLOSE, HLP_BOOK
}
public static Image getImage(ICON en) {
if (!images.containsKey(en)) {
switch (en) {
case HLP_BOOK:
images.put(en, new Image(IconFactory.class.getResourceAsStream("help_book.png"))); break;
default:
return null;
}
}
return images.get(en);
}
}
Usage after the update:
subMenuHelp.setGraphic(new ImageView(IconFactory.getImage(ICONS.HLP_BOOK)));

Eclipse RCP / JFace Wizard - How to programmatically force close wizardDialog from wizardPage

I have WizardDialog/Wizard and content is WizardPage. Lets say I am doing something inside Page, and when some error occurs I popup with MessageBox and after clicking on OK I want to force close wizardDialog.
Bad way is to call:
getShell().dispose;
because SWT throws and Exception:
!ENTRY org.eclipse.ui 4 0 2013-08-20 14:15:13.353
!MESSAGE Unhandled event loop exception
!STACK 0
org.eclipse.swt.SWTException: Widget is disposed
Instead it When I call:
getWizard().performCancel();
It does nothing.
How to force close Wizard without SWT Exception?
You should use "close" method on your wizard dialog object. To call it from a wizard page, I would suggest you to make a callback interface and pass it to the page. Something like that:
final YourWizard wizard = new YourWizard ();
WizardDialog wizardDialog = new WizardDialog(shell, wizard);
wizard.setErrorhandler(new YourCustomErrorHandlerInterface() {
#Override
public void onError() {
wizardDialog.close();
}
});
wizardDialog .open();
After, when wizard page is created you pass YourCustomErrorHandlerInterface to it. And when error occurs just call YourCustomErrorHandlerInterface#onError method, which will close the wizard.
Hope this helps.
I think you use cancelPressed() method on WizardDialog for close wizard dialog
BaseWizard baseWizard=new BaseWizard();
BaseWizardDialog baseWizardDialog=new BaseWizardDialog(getShell(),baseWizard);
baseWizard.setBaseWizardDialog(baseWizardDialog);
baseWizardDialog.open();
public class BaseWizard extends Wizard {
private BaseWizardDialog baseWizardDialog=null;
private BaseWizardPage baseWizardPage;
public BaseWizard()
{
super();
setWindowTitle("My Wizard");
baseWizardPage=new BaseWizardPage();
}
public void setBaseWizardDialog(BaseWizardDialog baseWizardDialog) {
this.baseWizardDialog = baseWizardDialog;
baseWizardPage.setBaseWizardDialog(this.baseWizardDialog);
}
public BaseWizardDialog getBaseWizardDialog() {
return baseWizardDialog;
}
}
public class BaseWizardPage extends WizardPage {
public void createControl(Composite parent) {
private BaseWizardDialog baseWizardDialog=null;
public void setBaseWizardDialog(BaseWizardDialog baseWizardDialog) {
this.baseWizardDialog = baseWizardDialog;
}
public BaseWizardDialog getBaseWizardDialog() {
return baseWizardDialog;
}
create first control and when you want to close the dialog simply write cancel pressed
if(ConditiontoClose==true)
getBaseWizardDialog().cancelPressed();
}
}
The Wizard implementation of this IWizard method disposes all the pages controls using DialogPage.dispose.
Subclasses should extend this method if the wizard instance maintains addition SWT resource that need to be disposed.
(Javadoc)
So, when you dispose the dialog, the pages after current page are not visible (I think) and loaded, that's why Wizard.close() matters (same for Wizard.getShell().close() I think).
The method performCancel should be implemented by MyWizard to define what should be done after user click on cancel but it is not defined in Wizard. It is called by the Wizard after the users clickon cancel. For example :
void close(){
dosmthng
performCancel();
dispose();
}
In fact this is the equivalent for performFinish(), but with the button cancel. I hope I was clear.
Maybe setVisible(false) should work.
This worked for me.
// fatal error situation detected on a wizard page
MessageDialog.openError(getShell(), "Error", "Wizard cannot continue and will now exit.");
getWizard().getContainer().getShell().close();
In my case, the only option that worked was:
getShell().setVisible(false);

Selection service gives the selection from original window instead of new window when used in conjunction with IHandler. eclipse RCP

I have an eclipse rcp application in which I have defined a key binding (CTRL+M) which processes the current selection in a tree view.
This is working as expected but whenever I open a new window using ActionFactory.OPEN_NEW_WINDOW.create(window), the key binding still works but it gets the selection from original window instead of newly opened window.
Any one know how to solve this problem?
IHandler Implementation:
public class MyHandler extends AbstractHandler{
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
processCurrentSelection(selection);
return null;
}
}

Getting all windows using UISpec4J

I am trying to use UISpec4J in order to automate a Java Swing application. After adapter setup:
setAdapter(new MainClassAdapter(Main.class, new String[0]));
I am trying to obtain the main window:
Window mainWindow = getMainWindow();
Instead of a login dialog, I am getting a splash screen with logo of application. All my attempts to call this dialog manually have failed.
How can I get the list of opened dialogs/windows?
It looks like MainClassAdapter is not designed to handle a sequence of windows. However you can implement your own adapter that ignores the splash screen and returns the subsequent window. Here is a sample taken from UISpec4J forums:
setAdapter(new UISpecAdapter() {
public Window getMainWindow() {
final Window[] result = new Window[1];
WindowInterceptor.init(new MainClassTrigger(Main.class, new String[0]))
.processTransientWindow()
.process(new WindowHandler() {
public Trigger process(Window window) throws Exception {
result[0] = window;
return Trigger.DO_NOTHING;
}
})
.run();
return result[0];
}
});

Categories