Opening one shell each time - java

In my project i have a shell, in the shell there are 3 buttons, i want that a click on each button will open a shell ,but i want that if a shell is already open due to a click on a button then that shell will be closed and a new shell will be opened.
(I dont want 2 shell from clicking buttons to be open at the same time)
But i have no idea how to do this.
In this class the opening of the shells should be.
public class ClickLabel implements MouseListener
{
Shell shell;
int p;
public ClickLabel(int p)
{
shell = new Shell();
this.p = p;
}
#Override
public void mouseDoubleClick(MouseEvent e) {}
#Override
public void mouseDown(MouseEvent e) {}
#Override
public void mouseUp(MouseEvent e) {
shell.open();
}
}
Can anyone help me?

Here is simple example with buttons and one active Shell, examine that:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Example{
public static void main(String[] args) {
new Example();
}
private Shell openedShell;
public Example() {
final Display display = new Display ();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
SelectionAdapter adapter = new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
if(openedShell != null){
openedShell.dispose();
}
openedShell = new Shell(display);
openedShell.setSize(200,200);
openedShell.setText(((Button)e.getSource()).getText());
openedShell.open();
}
};
for(int i =1;i<4;i++){
Button b = new Button(shell, SWT.PUSH);
b.setText("shell "+i);
b.addSelectionListener(adapter);
b.pack();
}
shell.pack();
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}

Related

Multiple threads in Java while using WindowBuilder SWT

Can someone explain me why Window in this program freezes while I try to run 2 or more threads ?
I want to be able to click on Hello button while both of threads are running.
Here is my simple project.
Task class only prints out word "Testing".
public class Task extends Thread {
public static boolean keepRun = true;
public void run(){
while(keepRun == true){
System.out.println("Testing...");
try {
Thread.sleep(1000);
}catch(InterruptedException e){}};
}
}
Closing class stops thread when it is typed stop inside console.
import java.util.Scanner;
public class Closing implements Runnable{
Scanner s = new Scanner(System.in);
public void run() {
while (s.next().equals("stop")){
System.out.println("Threads down");
Task.keepRun =false;
try {
Thread.sleep(5000);
}catch(InterruptedException e){}
};
}
}
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
Here is Window class where main is also located.
public class Window {
protected Shell shell;
/**
* Launch the application.
* #param args
*/
public static void main(String[] args) {
try {
Window window = new Window();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
protected void createContents() {
shell = new Shell();
shell.setSize(192, 208);
shell.setText("SWT Application");
Button btnRun = new Button(shell, SWT.NONE);
btnRun.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
Task newTask = new Task();
Closing closing = new Closing();
newTask.start();
closing.run();
}
});
btnRun.setBounds(50, 32, 75, 25);
btnRun.setText("Run");
Button btnHello = new Button(shell, SWT.NONE);
btnHello.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Hello");
}
});
btnHello.setBounds(50, 81, 75, 25);
btnHello.setText("Hello");
}
}
Rewrite this:
Closing closing = new Closing();
newTask.start();
closing.run();
to this:
Closing closing = new Closing();
newTask.start();
new Thread(closing).start();
Look at this code:
public class Closing implements Runnable{
Scanner s = new Scanner(System.in);
public void run() {
while (s.next().equals("stop")){
System.out.println("Threads down");
Task.keepRun =false;
try {
Thread.sleep(5000);
}catch(InterruptedException e){}
};
}
}
If you call simply run();, Thread.sleep(5000); will be affected to thread which called run, in the other hand, when you create a new Thread, sleep will be affected to this one.

Exception in thread "Thread-0" org.eclipse.swt.SWTError: XPCOM error 0x8000ffff

I am getting below Exception while running my program. It works fine when I use SWT.NONE instead of SWT.MOZILLA. But I need to use SWT.MOZZILLA, so I can manipulate the browser settings(like proxy settings) or request headers.
Exception in thread "Thread-0" org.eclipse.swt.SWTError: XPCOM error 0x8000ffff
at org.eclipse.swt.browser.Mozilla.error(Mozilla.java:2815)
at org.eclipse.swt.browser.Mozilla.initProfile(Mozilla.java:2617)
at org.eclipse.swt.browser.Mozilla.create(Mozilla.java:770)
at org.eclipse.swt.browser.Browser.<init>(Browser.java:101)
at OrderThread.openBrowser(MultiThreadBrowser.java:34)
at OrderThread.run(MultiThreadBrowser.java:26)
Here is my program, in this program, I am using XULRunner version 3.6.28, 32 bit which I downloaded here. I would really appreciate your response on this.
Adding additional information that, it works fine when I run this in single thread.
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.ProgressAdapter;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class MultiThreadBrowser {
public static void main(String args[]) {
String xulrunnerDir = "C:\\xulrunner-3.6.28.en-US.win32\\xulrunner";
System.setProperty("org.eclipse.swt.browser.XULRunnerPath", xulrunnerDir);
for (int i = 0; i < 2; i++) {
OrderThread ot = new OrderThread();
ot.start();
}
}
}
class OrderThread extends Thread {
boolean loaded = false;
public void run() {
openBrowser();
}
public void openBrowser() {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Browser browser = new Browser(shell, SWT.MOZILLA);
browser.setUrl("http://stackoverflow.com");
shell.open();
browser.addProgressListener(new ProgressAdapter() {
#Override
public void completed(ProgressEvent event) {
if (!loaded) {
loaded = true;
event.display.timerExec(5000, new Runnable() {
#Override
public void run() {
System.out.println("Loaded!!!");
shell.close();
}
});
}
}
});
while (display.getShells().length > 0) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}

Overriding Cut/Copy/Paste in SWT Text control

What is the correct way to override the cut(), copy(), and paste() methods of the Text control? What triggers the execution of these methods?
I have created an example application with a custom class that overrides these methods. Unfortunately, nothing seems to execute these overridden methods, including the act of using Ctrl+X / Ctrl+C / Ctrl+V or selecting cut/copy/paste from the context menu.
Custom Text Class:
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class TextCopyable extends Text{
public TextCopyable(Composite parent, int style) {
super(parent, style);
}
#Override
public void checkSubclass() {
}
#Override
public void cut() {
System.out.println("Cut!");
}
#Override
public void copy() {
System.out.println("Copy!");
}
#Override
public void paste() {
System.out.println("Paste!");
}
}
Test Shell:
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.layout.GridData;
public class CopyPasteTest extends Shell {
private TextCopyable text;
public static void main(String args[]) {
try {
Display display = Display.getDefault();
CopyPasteTest shell = new CopyPasteTest(display);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public CopyPasteTest(Display display) {
super(display, SWT.SHELL_TRIM);
createContents();
}
protected void createContents() {
setText("SWT Application");
setSize(450, 300);
GridLayout gridLayout = new GridLayout();
setLayout(gridLayout);
text = new TextCopyable(this, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
}
#Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}
My expectation was that the copy() method would be called any time that I use the Ctrl+C command to copy text from the textbox. However, the methods do not trigger at all. Is my assumption faulty?

Show Page loading no browser until page is fully loaded

I want to hide the content of html page until its fully loaded. The idea is I want to get the content of html page do some processing and set the content back again. For doing so I am able to retrieve the text and do some processing on it. But the problem is , till the time processing is not complete, I want to hide the original html page and instead wanna show some dummy page.
I want to hover a shell on browser window and remove it when the loading is complete. I tried to hide the browser widget but that is not working as per the expectations.
Here is the snippet for the same.
package browserapp;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.extended.LocationEvent;
import org.eclipse.swt.browser.extended.LocationListener;
import org.eclipse.swt.browser.extended.ProgressEvent;
import org.eclipse.swt.browser.extended.ProgressListener;
import org.eclipse.swt.browser.extended.Browser;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class MyBrowser_1 {
/**
* Runs the application
*/
Display display = new Display();
protected boolean done;
public void run() {
final Shell shell = new Shell(display);
shell.setText("Simple Browser");
createContents(shell);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
/**
* Creates the main window's contents
*
* #param shell the main window
*/
private void createContents(final Shell shell) {
shell.setLayout(new FormLayout());
// Create the composite to hold the buttons and text field
Composite controls = new Composite(shell, SWT.NONE);
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
controls.setLayoutData(data);
// Create the web browser
final Browser browser = new Browser(shell, SWT.NONE);
browser.addLocationListener(new LocationListener() {
#Override
public void changing(LocationEvent event) {
// TODO Auto-generated method stub
//browser.setVisible(false);
Image image = new Image(display,
"C:\\Documents and Settings\\My
Documents\\Pictures\\loadingAnimation.gif");
///shell.setBackgroundImage(image);
}
#Override
public void changed(LocationEvent event) {
// TODO Auto-generated method stub
}
});
browser.addProgressListener(new ProgressListener()
{
public void completed(ProgressEvent event)
{
}
public void changed(ProgressEvent event)
{
int progressWorked=0;
if (event.total == 0)
return;
done = (event.current == event.total);
int percentProgress = event.current * 100 / event.total;
System.out.println("Loading...");
if (done)
{
progressWorked = 0;
System.out.println("Loading completed...");
//browser.setVisible(true);
//maskPage(browser, maskedMap);
} else if (progressWorked == 0)
{
progressWorked = percentProgress;
} else
{
progressWorked = event.current;
}
}
});
data = new FormData();
data.top = new FormAttachment(controls);
data.bottom = new FormAttachment(100, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
browser.setLayoutData(data);
// Create the controls and wire them to the browser
controls.setLayout(new GridLayout(7, false));
// Create the back button
Button button = new Button(controls, SWT.PUSH);
button.setText("Back");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.back();
}
});
// Create the forward button
button = new Button(controls, SWT.PUSH);
button.setText("Forward");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.forward();
}
});
// Create the refresh button
button = new Button(controls, SWT.PUSH);
button.setText("Refresh");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.refresh();
}
});
// Create the stop button
button = new Button(controls, SWT.PUSH);
button.setText("Stop");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.stop();
}
});
// Create the address entry field and set focus to it
final Text url = new Text(controls, SWT.BORDER);
url.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
url.setText("https://netbanking.hdfcbank.com/netbanking/");
url.setFocus();
// Create the go button
button = new Button(controls, SWT.PUSH);
button.setText("Go");
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
browser.setUrl(url.getText());
}
});
GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, false);
Label status = new Label(controls, SWT.BORDER);
status.setLayoutData(gridData2);
// Allow users to hit enter to go to the typed URL
shell.setDefaultButton(button);
}
/**
* The application entry point
*
* #param args the command line arguments
*/
public static void main(String[] args) {
MyBrowser_1 browser=new MyBrowser_1();
browser.run();
}
}

MultiThreading with instance variable java

I have a class like,
Class A extends B {
String test = "";
String first = "";
public void testMethod() {
new Thread() {
public void run() {
testThreadMethod();
}
}.start();
}
public void testThreadMethod() {
System.out.println(first + " " + test);
}
}
The above class compiles fine. But in run time, the error is thrown in system.out.println() saying "invalid thread access".
Is there any wrong in the code. Accessing instance variables in multithread not allowed? Is there any way to access the instance variable inside the thread?
Thanks in advance.
EDITED NEW: To Reproduce the problem
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
public class SWTView extends ViewPart{
public static Display display;
public static Shell shell;
static Text sampleText;
static String testField1 = "";
static String firstField2 = "";
public static void main(String[] args) {
display = new Display();
shell = new Shell(display);
// Create a new Gridlayout with 2 columns
// where the 2 column do not have the
// same size
GridLayout layout = new GridLayout(2, false);
// set the layout of the shell
shell.setLayout(layout);
// Create a label and a button
sampleText = new Text(shell, SWT.NONE);
Label label = new Label(shell, SWT.NONE);
label.setText("A label");
Button button = new Button(shell, SWT.PUSH);
button.setText("Press Me");
// Create a new label that will spam two columns
label = new Label(shell, SWT.BORDER);
label.setText("This is a label");
// Create new layout data
GridData data = new GridData(GridData.FILL,
GridData.BEGINNING, true, false, 2, 1);
label.setLayoutData(data);
// Create a new label which is used as a separator
label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
// Create new layout data
data = new GridData(GridData.FILL, GridData.BEGINNING, true,
false, 2, 1);
data.horizontalSpan=2;
label.setLayoutData(data);
// Create a right aligned button
Button b = new Button(shell, SWT.PUSH);
b.setText("New Button");
b.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
new Thread() {
public void run() {
printInstanceVariables();
}
}.start();
//showProgressBar() ---> // This is been implemented in another file which will shoe progress bar
}
});
data = new GridData(GridData.END, GridData.BEGINNING, false,
false, 2, 1);
b.setLayoutData(data);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public static void printInstanceVariables() {
System.out.println("Text entered is :: " +sampleText.getText());
System.out.println("test Field 1 is :: " + testField1);
System.out.println("first Field 2 is :: " + firstField2);
}
#Override
public void createPartControl(Composite arg0) {
// TODO Auto-generated method stub
}
#Override
public void setFocus() {
shell.setFocus();
}
}
The above code will throw invalid thread acesses ecpection # printInstanceVariables() first system.out.println()
Answer: Got it.. It is because of accessing the component Text inside the thread in printInstanceVariables(). When i pass this component as paramter, everything works fine. Thanks for all you answers.
This program compiles and executes as expected (it prints a space and a new line). Your problem is somewhere else:
public class Test {
public static void main(String[] args) throws Exception {
A a = new A();
a.testMethod();
}
static class A {
String test = "";
String first = "";
public void testMethod() {
new Thread() {
public void run() {
testThreadMethod();
}
}.start();
}
public void testThreadMethod() {
System.out.println(first + " " + test);
}
}
}
I tried your code without extending class B and its working fine. What does your class B contain? Is there really any need to extend class B?
anonymous inner class is only allowed access FINAL member variable.
this is JVM specification.
i doubt why there is no warning when your code be compiled.
in fact i could get nothing out put when run these code. is there something wrong?
i rewrite the codes, test it and find
it can't access a member variable when the thread in anonymous inner class.
please see the output from eclipse.

Categories