Getting all windows using UISpec4J - java

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];
}
});

Related

How can I open a specific Tab of a Tabsheet with an Button in CUBA Platform?

I created a Dashboard with a menubutton fragment. When I click on a button a new Screen is opening. And now I want to open a specific tab of this screen. In default always the first tab of a screen opens up, but I need to specify. My code looks like this:
public void onBaldUeberfaelligBtnClick() {
screenBuilders.screen(this)
.withScreenClass(AufgabenuebersichtBrowse.class)
.build()
.show();
}
You can introduce a method in your AufgabenuebersichtBrowse class that switches to the needed tab. And then invoke this method after creating the screen, something like this:
public class AufgabenuebersichtBrowse extends ... {
#Inject
private TabSheet tabSheet;
public void switchToMyTab() {
tabSheet.setSelectedTab("tab2");
}
public void onBaldUeberfaelligBtnClick() {
AufgabenuebersichtBrowse screen = screenBuilders.screen(this)
.withScreenClass(AufgabenuebersichtBrowse.class)
.build();
screen.switchToMyTab();
screen.show();
}
See also the docs on opening screens: https://doc.cuba-platform.com/manual-7.2/opening_screens.html#screen_parameters

Active perspective is null if a view is detached

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);

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);

javafx webview not supporting Ajax web features

I am trying to open webpage in webview using JavaFx . Its opening the web page properly but its not supporting the Ajax based web features like partial refreshing and new window popup handling
I am using the following code
final Group group= new Group();
Scene scene= new Scene(group);
fxpanel.setScene(scene);
WebView webview = new WebView ();
group.getChildren().add(webview);
eng= webview.getEngine();
eng.setJavaScriptEnabled(true);
try{
String url="http://www.abc.com";
eng.load(url);
eng.setCreatePopupHandler(
new Callback<PopupFeatures, WebEngine>() {
#Override
public WebEngine call(PopupFeatures config) {
smallView = new WebView();
smallView.setFontScale(0.8);
ChatPopup frm = new ChatPopup(smallView);
frm.setBounds(0,0,400,250);
frm.setVisible(true);
return smallView.getEngine();
}
});
}
catch(Exception ex){}
}
WebView does support Ajax.
Run the following app.
Click on the "Load data from server into div" button.
Page will be refreshed with data fetched from the server.
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewAjax extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) {
WebView webView = new WebView();
webView.getEngine().load("http://www.jquerysample.com/#BasicAJAX");
final Scene scene = new Scene(webView);
stage.setScene(scene);
stage.show();
}
}
Aside on alerts
Note, in the sample page linked above there there are numerous examples for handling the json data. Some of the examples, e.g. the jquery $.get() example, output the result of the ajax call using a JavaScript alert().
If you want to see the alert data, you need to add an alert handler to the WebView engine. A basic alert handler such as below will just output the alert data to the output console:
webView.getEngine().setOnAlert(
stringWebEvent -> System.out.println(stringWebEvent.getData())
);
This is not really related to ajax calls, but without an alert handler, you may be confused you if you are trying to use an alert to debug or show data returned from a WebView ajax call.
If you need to make AJAX calls to cross-site services in the WebView, you can get around the security restrictions by making your AJAX calls through an up-call to Java. For example you could write or find a class with a ".request()" method that takes a JSObject as a parameter (the same JSObject format that jQuery's $.ajax() method takes, preferably), and inject a Java object that will expose that method:
WebView myWebView; //assuming it's initialized and points to an actual WebView
WebEngine engine = myWebView.getEngine();
JSObject window = null;
try{
window = (JSObject) engine.executeScript("window");
}catch (JSException e){
e.printStackTrace();
}
if (window != null){
window.setMember("myAjax", new AJAXProxyClass());
}
You can also directly override jQuery's ajax method with your own upcalling method, so that the difference is completely transparent to the javascript code, i.e.:
engine.executeScript("$.ajax = new function (o) { myAjax.request(o); };");
engine.executeScript("_$ = window.$");
This will replace jQuery's "$.ajax" call with the one from your Java object seamlessly. (I set the "_$" variable because jQuery will overwrite $ with it sometimes if it detects conflicts, returning jQuery to its original version.) This means that in most cases, any javascript code will not have to care whether it is running in your WebView or not.
A warning, though - jQuery's ajax call is rather complex, and this may break some of the jQuery ajax extensions if you're not careful about how you handle it. It should work just fine for the most common kinds of GET and POST calls, though.

GWT open page in a new tab

I am developing GWT application and I use
com.google.gwt.user.client.Window.open(pageUrl, "_blank", "");
to open new page. And it opens in a new tab when called, for example, directly after button click.
But I decided to do some validations on server before opening new page and placed the call to the mentioned above method to the
public void onSuccess(Object response) {
}
And it starts to open pages in new window instead of new tab (this is true only for Chrome, other browsers still open it in a new tab).
Can anybody help me?
I built a small example to illustrate the issue:
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Window.open("http://www.google.com/", "_blank", "");
MySampleApplicationServiceAsync serviceAsync = GWT.create(MySampleApplicationService.class);
serviceAsync.getMessage("Hello, Server!", new AsyncCallback() {
public void onFailure(Throwable caught) {
Window.alert("ERROR");
}
public void onSuccess(Object result) {
Window.open("http://www.bing.com/", "_blank", "");
}
}
);
}
});
Firefox(3.6.8) opens both pages in new tabs.
Chrome(6.0) opens "google.com" in new tab and "bing.com" in new window
Opera(10.10) opens in new tabs.
IE(8.0) opens both in new Windows.
I marked igorbel 's answer as the only correct cos I haven't found any proper way to specify the same behaviour in all situations.
I used this code and it works for me in google chrome and mozilla firefox 3.6.8 browsers
If you want to open a page in new window you should write code as
Window.open("www.google.com","_blank","enabled");
If you want to open a page in new tab you should write code as
Window.open("www.google.com","_blank","");
I am not sure you are going to be able to control this the way you want. The problem is that browsers can decide when to open windows and when to open tabs. For example, firefox has the option: "Open new windows in new tabs instead". And don't forget the browsers that don't support tabs (yes, those do still exist).
Since this is such a problematic aspect of the user experience, my recommendation would be to reconsider your design. Is it really that important for you application to differentiate between opening a new tab and opening a new window?
This code works for me:
Before calling the Async method keep a reference to a new window with empty parameters.
At onSuccess() method set the URL of the window.
Button someButton = new Button("test");
SelectionListener<ButtonEvent> listener = new SelectionListener<ButtonEvent>()
{
public void componentSelected(ButtonEvent ce)
{
final JavaScriptObject window = newWindow("", "", "");
someService.doSomething(new AsyncCallback()
{
public void onSuccess(Object o)
{
setWindowTarget(window, "http://www.google.com/");
}
});
}
}
someButton.addSelectionListener(listener);
private static native JavaScriptObject newWindow(String url, String name, String features)/*-{
var window = $wnd.open(url, name, features);
return window;
}-*/;
private static native void setWindowTarget(JavaScriptObject window, String target)/*-{
window.location = target;
}-*/;
Found at:
http://groups.google.com/group/google-web-toolkit/browse_thread/thread/574b3b828271ba17
Interesting thing,
chrome will open page in new tab in case if you put window.open(...) instruction into the body of the click handler implementation.
For example:
Button someButton = new Button("test",
new ClickHandler() {
public void onClick(ClickEvent event) {
Window.open(...);
}
});
And a page will be opened in the separate window in case if I will include any Async. request into the mentioned code:
Button someButton = new Button("test",
new ClickHandler() {
public void onClick(ClickEvent event) {
someService.doSomething(new AsyncCallback() {
void onSuccess(Object o) {
Window.open(...);
}
...
});
}
});
The way Chrome looks at it, calling Window.open() is like trying to open a pop-up window in the user's face. That's frowned upon and will trigger the built-in pop-up blocker. Following a link, according to Chrome, should be the result of a user clicking on a good old anchor tag with an href attribute. But here lies the answer you're looking for: you can show a link to the user and change the link target on the fly. That would qualify as a 'proper' link in Chrome's world.
This code works for me:
public static native String getURL(String url)/*-{
return $wnd.open(url,
'target=_blank')
}-*/;

Categories