Call JavaFX application twice - java

I would need help with the following: I am implementing an application in javafx, this application Is called through a click on a button.
The problem is that when I close the application then I can not call it again.
I have read that you can not call the Application.launch() method more than once.
But I found something on the service class. The examples in the documentation page are not very clear. Anyone have an idea of ​​how this could be done?
Thank you.
http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
my code:
private void jButton1ActionPerformed (java.awt.event.ActionEvent evt) {
WebMap n1 = new WebMap () / / application in javafx
n1.Lunch ();
}
WebMap class: / / javafx application
public void Lunch () {
Application.launch ();
}

You can't launch a JavaFX application more than once in the same process, so don't try to do that.
You need to find an alternative mechanism to do whatever it is you are trying to do.
If you are embedding JavaFX scenes in a Swing application you should be creating new JFXPanels in Swing, not creating new JavaFX Applications on Swing button presses.
If you are intending to have a pure JavaFX application, then there is no need to have a Swing button which launches a JavaFX application, you can just use a JavaFX button instead and directly display the JavaFX scene.
There is no need to use a Service in this case, Service is used for performing repeated background tasks on a another thread, which has nothing to do with what you are attempting.
Read JavaFX for Swing developers if you want to integrate a Swing and JavaFX application.

As a committer of the com.bitplan.javafx open source project I can point you to the work-around we have been using for a while now:
https://github.com/BITPlan/com.bitplan.javafx/blob/master/src/main/java/com/bitplan/javafx/WaitableApp.java
WaitableApp.toolkitInit();
will initialize the JavaFX environment.
https://github.com/BITPlan/com.bitplan.javafx/blob/master/src/main/java/com/bitplan/javafx/SampleApp.java
will show an example of how the WaitableApp base class is used in general. You also might want to have a look at the Junit Testcases of the project.
WaitableApp
/**
* Waitable Application that does not need launch
*
* #author wf
*
*/
public abstract class WaitableApp extends Application {
protected Stage stage;
static boolean toolkitStarted;
/**
* allow startup without launch
*/
#SuppressWarnings("restriction")
public static void toolkitInit() {
if (!toolkitStarted) {
toolkitStarted = true;
// do not exit on close of last window
// https://stackoverflow.com/a/10217157/1497139
Platform.setImplicitExit(false);
/// https://stackoverflow.com/a/38883432/1497139
// http://www.programcreek.com/java-api-examples/index.php?api=com.sun.javafx.application.PlatformImpl
com.sun.javafx.application.PlatformImpl.startup(() -> {
});
}
}
#Override
public void start(Stage stage) {
this.stage = stage;
}
public Stage getStage() {
return stage;
}
public void setStage(Stage stage) {
this.stage = stage;
}
/**
* wait for close
*
* #throws InterruptedException
*/
public void waitStatus(boolean open) {
int sleep = 1000 / 50; // human eye reaction time
try {
if (open)
while ((stage == null) || (!stage.isShowing())) {
Thread.sleep(sleep);
}
else
while (stage != null && stage.isShowing()) {
Thread.sleep(sleep);
}
} catch (InterruptedException e) {
ErrorHandler.handle(e);
}
}
public void waitOpen() {
waitStatus(true);
}
public void waitClose() {
waitStatus(false);
}
/**
* show me
*/
public void show() {
// ignore multiple calls
if (stage != null)
return;
Platform.runLater(() -> {
try {
this.start(new Stage());
} catch (Exception e) {
ErrorHandler.handle(e);
}
});
}
/**
* close this display
*/
public void close() {
Platform.runLater(() -> {
if (stage != null)
stage.close();
});
this.waitClose();
// allow reopening
stage = null;
}
}

Related

How To Have Code Run For A Real Time Update For Condition Met Without The Need Of An Event(Button For Example) Java

I am trying to make a password checker, and I am trying to have an icon set as X until the user meets the condition of the password being at least 8 characters long. I am trying to set up a while loop for while the program is running, which will in turn run another while loop which will update the icon. I am doing this because a want it to always be checking to see if the condition is met and not need the user to click a button for example. I have placed the code inside the initComponents of the public form PasswordCheckerUI, but when I hit run on the program, it says running but my GUI doesn't pop up. How would I change the code to make this work(if needed) or where would I have to move it to? I have tried making a public static void with the code and calling it within the initCompnents, but it yielded the same results. Lastly, I tried to call the method within the main method, but the variables aren't static so that did not work either
public class PasswordCheckerUI extends javax.swing.JFrame {
public PasswordCheckerUI() {
initComponents();
while (Thread.currentThread().isAlive()) {
while (txtPassword.getText().length() < 8) {
lblMinCharIcon.setIcon(X);
if (txtPassword.getText().length() >= 8) {
lblMinCharIcon.setIcon(Check);
}
}
}
}
}
Events in Swing don't just happen when the user clicks on a button - they happen all the time (when moving the mouse, when clicking, when editing text, when ...) and they are therefore the best way to solve your problem.
You can for example listen the document change events on the txtPassword and change the icon depending on the new length of the password:
public class PasswordCheckerUI {
private JTextField txtPassword;
private JLabel lblMinCharIcon;
public PasswordCheckerUI() {
txtPassword = new JTextField(40);
txtPassword.getDocument().addDocumentListener(
new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
checkPasswordLen(txtPassword);
}
#Override
public void removeUpdate(DocumentEvent e) {
checkPasswordLen(txtPassword);
}
#Override
public void changedUpdate(DocumentEvent e) {
checkPasswordLen(txtPassword);
}
}
);
}
private void checkPasswordLen(JTextField tf) {
if (tf.getText().length() < 8) {
lblMinCharIcon.setIcon(x);
} else {
lblMinCharIcon.setIcon(check);
}
}
}

Dispose frame after start frame Java Swing

I'm new to Stackoverflow. I have a problem in java/swing with project to school.
The project is a testing service. I want to run an additional window before running the main program that checks the connection to the server. After checking the connection it should start the main window of the program and disappear. If I manually click startProgramButton it's all right. However, if the program is connected to the server at startup, the main window of the program is started, but this window does not disappear.
public class PreForm extends javax.swing.JFrame {
/**
* Creates new form PreForm
*/
MainForm form1;
Settings form2;
public PreForm() {
initComponents();
checkConnection();
}
private void settingsButtonActionPerformed(java.awt.event.ActionEvent evt) {
errorLabel.setText("");
form2 = new Settings();
form2.setVisible(true);
}
private void runProgramButtonActionPerformed(java.awt.event.ActionEvent evt) {
checkConnection();
}
private void checkConnection() {
if (hostAvailabilityCheck()) {
runMainProgram();
} else
errorLabel.setText("<html>Error connect to server!<br>"
+ "Check connect settings and try again!</html>");
}
private boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SettingsFile.getAddress(), Integer.parseInt(SettingsFile.getPort()))) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
private void runMainProgram() {
this.setVisible(false);
form1 = new MainForm();
form1.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new PreForm().setVisible(true);
}
});
}
So, after running the program, the checkConnection method is executed. Then the runMainProgram method is executed. And that's where this.setVisible (false) code comes in, which should hide the window, but it stays. But only if the checkConnection method is started in the constructor. If you run it manually through the startProgramButton, this window is hidden.

How to call default close operation of a stage in javafx?

I wrote the defaultCloseOperation function of the primaryStage, but I have an exit button too and I want to run that defaultCloseOperation.
I tried to call the close() and the hide() methods of the stage but it exit immediately without calling my defaultCloseOperation function, but I need to call it because I need to release all the resources from the server side when I close the client.
Do not do this on a closing operation of a Stage.
This is what the Application.stop method should be used for.
#Override
public void stop() throws Exception {
// TODO: release resources here
}
If there are resources used for one of multiple windows however, you should use an event handler for the onHidden event - no need to extend Stage:
stage.setOnHidden(event -> {
// TODO: release resources here
});
you can see it:
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
#Override public void handle(WindowEvent t) {
System.out.println("CLOSING");
}
});
and here:
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
// take some action
...
// close the dialog.
Node source = (Node) actionEvent.getSource();
Stage stage = (Stage) source.getScene().getWindow();
stage.close();
}
}
more of explanation you can read here

How to create hyperlink in Messagebox.show in ZK in Java?

In my ZK project with Java, I need to show a message box in which there needs to be a hyperlink, from which user can open another web page.
How can I achieve this?
According to the documentation, the customization of the MessageBox is rather limited. There is a possibilty to completely change the UI via MessageBox.setTemplate(), but this affects all MessageBoxes.
In our project, we replaced zk's default MessageBox with our own, which works more like a dialog. With this, we are in full control over the content of the dialog.
public abstract class OurDialog
{
private Window window;
private DialogListener closeListener;
public OurDialog(String title)
{
window = new Window();
window.setTitle(title);
window.setHflex("min");
window.setSizable(false);
window.setPosition("center");
window.setContentStyle("overflow: auto");
window.addEventListener(Events.ON_CLOSE, new EventListener<Event>()
{
#Override
public void onEvent(Event event)
throws Exception
{
if (closeListener != null)
{
if ("confirmed".equals(event.getData()))
{
closeListener.onClose(OurDialog.this);
if (!closeListener.onCloseConfirmation(OurDialog.this))
{
event.stopPropagation();
}
}
else
{
closeListener.onCancel(OurDialog.this);
if (!closeListener.onCancelConfirmation(OurDialog.this))
{
event.stopPropagation();
}
}
}
}
});
}
public final void setWidth(int width)
{
if (width != 0)
{
window.setMinwidth(width);
window.setWidth(width + "px");
}
else
{
window.setHflex("min");
}
}
public final void setHeight(int height)
{
if (height != 0)
{
window.setMinheight(height);
window.setHeight(height + "px");
}
else
{
window.setVflex("min");
}
}
public final void close()
{
Events.sendEvent(Events.ON_CLOSE, window, "confirmed");
}
public final void cancel()
{
Events.sendEvent(Events.ON_CLOSE, window, "cancelled");
}
/**
* #param closeListener called when the dialog is closed.
*/
public final void show(DialogListener closeListener)
{
setCloseListener(closeListener);
window.appendChild(getContent());
GUIHelper.setFocusToFirstInput(window);
OurMeatApplication.getCurrent().showDialog(this);
}
/**
* #return the component to be displayed in the dialog.
*/
protected abstract Component getContent();
}
Our main application class (OurApplication) has a reference to the page and provides the method to show the dialog:
final void showDialog(final OurDialog dialog)
{
Window window = dialog.getWindow();
window.setParent(page);
window.doModal();
}
This is a very generic dialog implementation for pretty much any purpose. For the specific MessageBox case, we have a sub class that provides a prepared UI, error level indicators, several buttons to pick, and a specialised listener to listen to those buttons.

java.lang.IllegalStateException: Application launch must not be called more than once - JavaFX (first once works, the 2nd non-) [duplicate]

How to call the launch() more than once in java i am given an exception as "ERROR IN MAIN:java.lang.IllegalStateException: Application launch must not be called more than once"
I have create rest cleint in my java application when request comes it call javafx and opening webview after completing webview operarion am closing javafx windows using Platform.exit() method. when second request comes am getting this error how to reslove this error.
JavaFx Application Code:
public class AppWebview extends Application {
public static Stage stage;
#Override
public void start(Stage _stage) throws Exception {
stage = _stage;
StackPane root = new StackPane();
WebView view = new WebView();
WebEngine engine = view.getEngine();
engine.load(PaymentServerRestAPI.BROWSER_URL);
root.getChildren().add(view);
engine.setJavaScriptEnabled(true);
Scene scene = new Scene(root, 800, 600);
stage.setScene(scene);
engine.setOnResized(new EventHandler<WebEvent<Rectangle2D>>() {
public void handle(WebEvent<Rectangle2D> ev) {
Rectangle2D r = ev.getData();
stage.setWidth(r.getWidth());
stage.setHeight(r.getHeight());
}
});
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("app", new BrowserApp());
stage.show();
}
public static void main(String[] args) {
launch(args);
}
RestClient Method:
Calling to JavaFX application
// method 1 to lanch javafx
javafx.application.Application.launch(AppWebview.class);
// method 2 to lanch javafx
String[] arguments = new String[] {"123"};
AppWebview .main(arguments);
You can't call launch() on a JavaFX application more than once, it's not allowed.
From the javadoc:
It must not be called more than once or an exception will be thrown.
Suggestion for showing a window periodically
Just call Application.launch() once.
Keep the JavaFX runtime running in the background using Platform.setImplicitExit(false), so that JavaFX does not shutdown automatically when you hide the last application window.
The next time you need another window, wrap the window show() call in Platform.runLater(), so that the call gets executed on the JavaFX application thread.
For a short summary implementation of this approach:
See the answer by sergioFC
If you are mixing Swing you can use a JFXPanel instead of an Application, but the usage pattern will be similar to that outlined above.
For an example of the JFXPanel apprach, see Irshad Babar
s answer.
Wumpus Sample
This example is bit more complicated than it needs to be because it also involves timer tasks. However it does provide a complete stand-alone example, which might help sometimes.
import javafx.animation.PauseTransition;
import javafx.application.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.*;
// hunt the Wumpus....
public class Wumpus extends Application {
private static final Insets SAFETY_ZONE = new Insets(10);
private Label cowerInFear = new Label();
private Stage mainStage;
#Override
public void start(final Stage stage) {
// wumpus rulez
mainStage = stage;
mainStage.setAlwaysOnTop(true);
// the wumpus doesn't leave when the last stage is hidden.
Platform.setImplicitExit(false);
// the savage Wumpus will attack
// in the background when we least expect
// (at regular intervals ;-).
Timer timer = new Timer();
timer.schedule(new WumpusAttack(), 0, 5_000);
// every time we cower in fear
// from the last savage attack
// the wumpus will hide two seconds later.
cowerInFear.setPadding(SAFETY_ZONE);
cowerInFear.textProperty().addListener((observable, oldValue, newValue) -> {
PauseTransition pause = new PauseTransition(
Duration.seconds(2)
);
pause.setOnFinished(event -> stage.hide());
pause.play();
});
// when we just can't take it anymore,
// a simple click will quiet the Wumpus,
// but you have to be quick...
cowerInFear.setOnMouseClicked(event -> {
timer.cancel();
Platform.exit();
});
stage.setScene(new Scene(cowerInFear));
}
// it's so scary...
public class WumpusAttack extends TimerTask {
private String[] attacks = {
"hugs you",
"reads you a bedtime story",
"sings you a lullaby",
"puts you to sleep"
};
// the restaurant at the end of the universe.
private Random random = new Random(42);
#Override
public void run() {
// use runlater when we mess with the scene graph,
// so we don't cross the streams, as that would be bad.
Platform.runLater(() -> {
cowerInFear.setText("The Wumpus " + nextAttack() + "!");
mainStage.sizeToScene();
mainStage.show();
});
}
private String nextAttack() {
return attacks[random.nextInt(attacks.length)];
}
}
public static void main(String[] args) {
launch(args);
}
}
Update, Jan 2020
Java 9 added a new feature called Platform.startup(), which you can use to trigger startup of the JavaFX runtime without defining a class derived from Application and calling launch() on it. Platform.startup() has similar restrictions to the launch() method (you cannot call Platform.startup() more than once), so the elements of how it can be applied is similar to the launch() discussion and Wumpus example in this answer.
For a demonstration on how Platform.startup() can be used, see Fabian's answer to How to achieve JavaFX and non-JavaFX interaction?
I use something like this, similar to other answers.
private static volatile boolean javaFxLaunched = false;
public static void myLaunch(Class<? extends Application> applicationClass) {
if (!javaFxLaunched) { // First time
Platform.setImplicitExit(false);
new Thread(()->Application.launch(applicationClass)).start();
javaFxLaunched = true;
} else { // Next times
Platform.runLater(()->{
try {
Application application = applicationClass.newInstance();
Stage primaryStage = new Stage();
application.start(primaryStage);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
try this, I tried this and found successful
#Override
public void start() {
super.start();
try {
// Because we need to init the JavaFX toolkit - which usually Application.launch does
// I'm not sure if this way of launching has any effect on anything
new JFXPanel();
Platform.runLater(new Runnable() {
#Override
public void run() {
// Your class that extends Application
new ArtisanArmourerInterface().start(new Stage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}

Categories

Resources