-->

Opening a new Window with Java RCP and SWT

2019-08-03 19:06发布

问题:

I'm currently developing an app, and for this, I'm using Java RCP with SWT.

What I want :

I have a window, and when I click on a Button, i need a whole window to be opened. The window works perfectly and looks like this :

Window1

When I press it, a new window opens. It looks like this :

Window2 (Yup, the middle pic has its importance)

How it's currently done :

The Window 1 is a TrimmedWindow done with the Application.e4xmi, with some Parts in. The button is included in one of these parts. Here's its code :

@PostConstruct
public void postConstruct(Composite parent) {
    Button b = new Button(parent, SWT.BORDER);  
    b.setText("Press me !");
    b.addListener(SWT.Selection, new Listener() {

        @Override
        public void handleEvent(Event event) {
            parent.getShell().dispose();
            new Game(Display.getCurrent());
        }
    });
}

The Window 2, as you can see, is a new class called Game. Its constructor is as follows :

public Game(Display display) {
    this.display = display;
    this.shell = new Shell(this.display);
    this.setData();
    shell.setText("I don't work properly");
    shell.setMinimumSize(800, 600);

    this.buildUI();

    shell.pack();
    shell.open();

    while (!shell.isDisposed()) {
        if (!this.display.readAndDispatch ()) this.display.sleep ();
    }
    this.display.dispose ();
}

What's the problem ? :

When I launch the project with Eclipse, everything goes WELL. I mean, really. I click, it opens, it loads, yay ! But the idea after this is I export the project as an executable. So I do it. Here's my .exe file. And let's start. And it doesn't work. When I press the button, nothing happens. Not even an error message, nothing.

I've found some solution that says the problem comes from the display, because RCP is single threaded. So I followed the instructions, and here's another version of the Game constructor :

public Game() {
    this.display = Display.getDefault();
    this.display.asyncExec(new Runnable() {

        @Override
        public void run() {
            shell = new Shell(display);
            setData();
            shell.setText("I work better but...");
            shell.setMinimumSize(800, 600);

            buildUI();

            shell.pack();
            shell.open();

            while (!shell.isDisposed()) {
                if (!display.readAndDispatch ()) display.sleep ();
            }
            display.dispose ();
        }
    });
}

And so here comes the new problem : I can't call an Image after this (hence the pic I showed on Window 2). Because Image (SWT) requires a display to be constructed, and because display doesn't work well without the Runnable instance, I can't use an image after this. And I need my Image here (and also somewhere else after this).

Edit : I have an error message in that case. It says :

org.eclipse.swt.SWTException : Failed to execute runnable (java.lang.IllegalArgumentException : Argument cannot be null)

Any solutions anyone please ?

Thanks in advance.

Kosnyru.

回答1:

If you add a Trimmed Window (or just a plain Window) to the 'Windows and Dialogs' section of the Application.e4xmi with 'To Be Rendered' turned off (leave Visible on) you can then show it using:

@Inject
EModelService modelService;
@Inject
MApplication app;


MUIElement window = modelService.find("window id", app);

window.setToBeRendered(true);


标签: java swt rcp e4