I created an eclipse wizard which i want to test now with the SWTBot. I already used the SWTWorkbenchBot which finally works but i want to test the wizard now without the eclipse workbench. Thats why i created a shell in my testclass where i want to put on my wizardpage, but all i could see, was a empty shell without my wizardPage.
So i created a new shell class which included this code:
public static void main(String args[]) {
try {
Display display = Display.getDefault();
HorrorShell shell = new HorrorShell(display);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create the shell.
*
* #param display
*/
public HorrorShell(Display display) {
super(display, SWT.SHELL_TRIM);
setLayout(new FillLayout());
createContents();
}
/**
* Create contents of the shell.
*/
protected void createContents() {
setText("SWT Application");
setSize(450, 300);
ManualSettingsWizardPage page = new ManualSettingsWizardPage();
page.createControl(this);
}
With the shell class it works, my wizardpage was shown but if i try to run my testclass as SWTBotTest or as JUnitTest it wont show me anything but a empty shell.
Here's the code in my testclass:
private ManualSettingsWizardPage wizard;
private SWTBotShell botShell;
private Shell shell;
private Display display;
private SWTBot bot;
#Before
public void setUp() {
botShell = new SWTBotShell(shell);
bot = new SWTBot();
wizard = new ManualSettingsWizardPage();
display = Display.getDefault();
shell = new Shell(display);
shell.open();
shell.layout();
}
#Test
public void bot() throws Exception {
bot = botShell.bot();
shell.setBounds(200, 200, 400, 400);
shell.setLayout(new FillLayout());
wizard.createControl(shell);
}
I think your problem stems from the fact that you are creating GUI components from the SWTBot-Thread. They should be created by the UIThread, though.
Normally, you'd test some plugin which would open a wizard as the result of choosing an action, e.g. "new xyz". First step would be to put your wizard code into a plugin and register a new action that would fire up the wizard. then you could try finding the shell with SWTBot and executing the desired actions.
Related
Using java, i created a shell and then opened the browser inside the shell, i want to move the shell to top right corner of the screen. I am trying to use setBound function, but it is not working.. how do i find the coordinates of the top right screen.
How to set the shell to a specific location
Code:
{
final Shell shell = new Shell();
shell.setLayout(new FillLayout());
Browser browser = new Browser(shell, SWT.NONE);
browser.setBounds( x, y, 200 ,200);
}
You can find the top right of the screen by getting the bounds of the Monitor:
final Monitor monitor = Display.getCurrent().getPrimaryMonitor();
final Rectangle monitorBounds = monitor.getBounds();
final Point topRight = new Point(monitorBounds.x + monitorBounds.width, monitorBounds.y);
If you want to account for multiple monitors, you can use Display#getMonitors(), and implement some logic to pick the Monitor that you care about.
You're on the right track for positioning the Shell. You can use the topRight Point from above, and subtract the width of the Shell to keep it on-screen. Alternatively there is a Shell#setLocation(Point) method that you can use.
For example:
public class ShellLocationTest {
private final Display display;
private final Shell shell;
public ShellLocationTest() {
display = new Display();
shell = new Shell(display, SWT.NONE);
final Point shellSize = new Point(400, 200);
shell.setSize(shellSize);
shell.setLayout(new FillLayout());
final Rectangle monitorBounds = display.getPrimaryMonitor().getBounds();
final Point shellLocation = new Point(monitorBounds.x + monitorBounds.width - shellSize.x, monitorBounds.y);
shell.setLocation(shellLocation);
}
public void run() {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
public static void main(String... args) {
new ShellLocationTest().run();
}
}
I used SWT browser. I opened page and there is a Button which verify that browser have option to open new browser window. Standard SWT browser have problem with it. Above is how button is defined.
<button class="btn btn-action btn-slim size-w-90pct" data-e2e="openDealerBtn" ng-if="igDefaultRowController.account.isPdSupported" ng-class="{'btn-disabled': igDefaultRowController.shouldDisableOpenPlatformButton}" ng-disabled="igDefaultRowController.shouldDisableOpenPlatformButton" ng-click="igDefaultRowController.openDealer()" ig-click-tracking="pureDealBtn-CFD" id="openDealerButton-XQ7JI"> <span class="btn-label" ig-i18n="" key="AccountOverview.openDealer"><span ng-bind-html="value">Open classic platform</span></span> </button>
[SOLVED!] How to expand SWT browser to open more than one tab ?
I used TabFolder for more tabs.
It is possible to catch URL after click on this button and open in new SWT browser tab ?
SWT uses one of the browsers that are available on the operating system and embeds the main "view" of the browser (the bit that displays the html) in your application. That does mean, however, that it doesn't come with all the fancy stuff like tabs.
As you already discovered yourself, you can get around this by using a TabFolder.
The question now is: how do you know when a tab should be opened. This code (adopted from Snippet270) should help you with this:
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Main Window");
shell.setLayout(new FillLayout());
final Browser browser;
try
{
browser = new Browser(shell, SWT.NONE);
}
catch (SWTError e)
{
System.out.println("Could not instantiate Browser: " + e.getMessage());
display.dispose();
return;
}
initialize(display, browser);
shell.open();
browser.setUrl("http://www.w3schools.com/html/tryit.asp?filename=tryhtml_links_target");
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
/* register WindowEvent listeners */
static void initialize(final Display display, Browser browser)
{
browser.addOpenWindowListener(e ->
{
Shell shell = new Shell(display);
shell.setText("New Window");
shell.setLayout(new FillLayout());
Browser browser1 = new Browser(shell, SWT.NONE);
initialize(display, browser1);
e.browser = browser1;
});
browser.addVisibilityWindowListener(new VisibilityWindowListener()
{
#Override
public void hide(WindowEvent e)
{
Browser browser = (Browser) e.widget;
Shell shell = browser.getShell();
shell.setVisible(false);
}
#Override
public void show(WindowEvent e)
{
Browser browser = (Browser) e.widget;
final Shell shell = browser.getShell();
if (e.location != null) shell.setLocation(e.location);
if (e.size != null)
{
Point size = e.size;
shell.setSize(shell.computeSize(size.x, size.y));
}
shell.open();
}
});
browser.addCloseWindowListener(e ->
{
Browser browser1 = (Browser) e.widget;
Shell shell = browser1.getShell();
shell.close();
});
}
This will open the link in a new Shell with a new Browser. You can change this, so it creates a new tab and adds the new browser to the new tab.
EDIT
Here's a working example using TabFolder:
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Main Window");
shell.setLayout(new FillLayout());
TabFolder tabFolder = new TabFolder(shell, SWT.BORDER);
addNewBrowser(tabFolder, "<a href='http://www.google.co.uk' target='_blank'>Click here!</a>");
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static Browser addNewBrowser(TabFolder folder, String html)
{
TabItem item = new TabItem(folder, SWT.NONE);
Composite c = new Composite(folder, SWT.NONE);
item.setControl(c);
c.setLayout(new FillLayout());
Browser browser = new Browser(c, SWT.NONE);
if (html != null)
{
browser.setText(html);
item.setText("Original tab");
}
else
{
item.setText("New tab");
}
browser.addOpenWindowListener(e ->
{
e.browser = addNewBrowser(folder, null);
});
browser.addVisibilityWindowListener(new VisibilityWindowListener()
{
#Override
public void hide(WindowEvent e)
{
Browser browser = (Browser) e.widget;
Shell shell = browser.getShell();
shell.setVisible(false);
}
#Override
public void show(WindowEvent e)
{
Browser browser = (Browser) e.widget;
final Shell shell = browser.getShell();
if (e.location != null) shell.setLocation(e.location);
if (e.size != null)
{
Point size = e.size;
shell.setSize(shell.computeSize(size.x, size.y));
}
shell.open();
}
});
browser.addCloseWindowListener(e ->
{
Browser browser1 = (Browser) e.widget;
Shell shell = browser1.getShell();
shell.close();
});
folder.setSelection(item);
return browser;
}
I wanted to create filter in java for browse file dialogue it should allow only either abc.exe or xyz.exe
I am using swt.widgets.FileDialog
currently I am filtering for *.exe with following string
String[] extensionFilter = { "*.exe" };
fileDialog .setFilterExtensions(extensionFilter);
How can I change this to allow only only abc.exe xyz.exe?
It should search for abc.exe and xyz.exe
example: When you allow multiple extensions(.exe,.dat) it will search for all files with that(.exe,.dat) extensions similarly I want to search for abc.exe and xyz.exe
Thanks in advance
You can use setFilterExtension(String[]), however you have to know how to format the String:
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Choose");
button.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
FileDialog dialog = new FileDialog(shell);
dialog.setFilterExtensions(new String[] { "abc.exe;xyz.exe" });
System.out.println(dialog.open());
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}
The single String "abc.exe;xyz.exe" tells it that both these are allowed.
Try this
String[] extensionFilter = { "abc.exe","xyz.exe" };
You can use setFilterNames
Which is explained here
It allows String type array variable only. No need to bother about regEx
String[] extensionFilter = { "abc.exe;xyz.exe" };
fileDialog.setFilterExtensions( extensionFilter );
AWT/Swing allows to show application modal (blocking the whole application) and parent modal (blocking only the parents) dialogs. How can I achieve the same with SWT?
In order to block the whole application, you can create the dialog Shell with the style SWT.APPLICATION_MODAL, open it, and then pump the UI events until the shell is disposed:
Display display = Display.getDefault();
Shell dialogShell = new Shell(display, SWT.APPLICATION_MODAL);
// populate dialogShell
dialogShell.open();
while (!dialogShell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
If you want to block input only to the parent, try using the style SWT.PRIMARY_MODAL, though the Javadocs specify (as for the other modal styles) that this is a hint; i.e., that different SWT implementations may not exactly handle it the same way. Likewise, I don't know of an implementation that would honor the SWT.SYSTEM_MODAL style.
UPDATE: Answer to first comment
If you have two or more primary modals open at the same time, you cannot use the tricks to pump the events until the modal is closed, as they could be closed in any order. The code will run, but execution will resume after the while loop after the current dialog is closed and all other such dialogs that have been opened after it. In this case, I would register a DisposeListener on each dialog to get a callback when they are closed. Something like this:
void run() {
Display display = new Display();
Shell shell1 = openDocumentShell(display);
Shell shell2 = openDocumentShell(display);
// close both shells to exit
while (!shell1.isDisposed() || !shell2.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
Shell openDocumentShell(final Display display) {
final Shell shell = new Shell(display, SWT.SHELL_TRIM);
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Open Modal Dialog");
button.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Button pressed, about to open modal dialog");
final Shell dialogShell = new Shell(shell, SWT.PRIMARY_MODAL | SWT.SHEET);
dialogShell.setLayout(new FillLayout());
Button closeButton = new Button(dialogShell, SWT.PUSH);
closeButton.setText("Close");
closeButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
dialogShell.dispose();
}
});
dialogShell.setDefaultButton(closeButton);
dialogShell.addDisposeListener(new DisposeListener() {
#Override
public void widgetDisposed(DisposeEvent e) {
System.out.println("Modal dialog closed");
}
});
dialogShell.pack();
dialogShell.open();
}
});
shell.pack();
shell.open();
return shell;
}
I have the following SWT test code:
public static void main(String[] args) {
shell = new Shell();
shell.setText(APP_NAME + " " + APP_VERSION);
shell.addShellListener(new ShellListener() {
public void shellActivated(ShellEvent event) { }
public void shellClosed(ShellEvent event) { exit(); }
public void shellDeactivated(ShellEvent event) { }
public void shellDeiconified(ShellEvent event) { }
public void shellIconified(ShellEvent event) { }
});
shell.open();
display = shell.getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
My exit() method is as follows:
private void exit() {
System.exit(0);
}
I try to quit the application by closing the shell ("window") or by pulling down the application menu (labeled "SWT") and selecting "Quit".
When I do this, a SWT stub is left behind in the Dock and the SWT application has not actually exited. I have to manually terminate the SWT application through Eclipse or via Force Quit.
I have tried this with the v3.4 and v3.5 SWT jars, under Eclipse 3.4.1 under Mac OS X 10.5.6 (Intel).
Is there additional work I need to do to be able to quit the application when I close the shell?
You are not releasing the native resources correctly - you have a resource leak.
You don't need to do this:
private void exit() {
System.exit(0);
}
The main method will exit when the shell is disposed. If you must use an exit method, call it after you've disposed all SWT resources:
Display display = new Display();
try {
Shell shell = new Shell(display);
try {
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} finally {
if (!shell.isDisposed()) {
shell.dispose();
}
}
} finally {
display.dispose();
}
System.exit(0);
When you allocated the Shell:
shell = new Shell();
some native resources were allocated along with it. You have to dispose of these resources before you exit your application:
private void exit() {
shell.dispose();
System.exit(0);
}
Of course, you have to provide the "shell" variable to your exit() method to do this.
Note that I don't believe that you need to dispose the Display, since you didn't create it with "new Display()". But anything in SWT (except for a few items where this is documented in the JavaDoc) that you create with new you must dispose when you are finished with it. Otherwise you will leak native resources.