问题
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);
来源:https://stackoverflow.com/questions/42256476/opening-a-new-window-with-java-rcp-and-swt