Issue
I have this code to open a custom Java browser:
private void openNavigator(){
Navigator browser = new Navigator();
SwingUtilities.invokeLater(() -> {
browser.initComponents();
browser.setVisible(true);
browser.loadURL("http://XXXXXXXX:8888/YYYYYY/ZZZZ");
});
}
In the other hand i have the code of the navigator:
public class Navigator extends JFrame {
private static final Logger LOG = Logger.getLogger(Navegador.class.getName());
private static final long serialVersionUID = -1951385676682823399L;
private WebView view;
private JFXPanel javaFxPanel;
private WebEngine engine;
private JLabel labelStatus;
private JTextField direction;
private JProgressBar progressBar;
private java.net.CookieManager cookiesManager;
public void initComponents() {
if (cookiesManager != null) {
cookiesManager = new java.net.CookieManager();
java.net.CookieHandler.setDefault(cookiesManager);
}
javaFxPanel = new JFXPanel();
labelStatus = new JLabel();
JPanel panelTodo = new JPanel(new BorderLayout());
JButton botonBuscar = new JButton("Search");
direction = new JTextField();
progressBar = new JProgressBar();
createScene();
ActionListener direcctionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadURL(direction.getText());
}
};
botonBuscar.addActionListener(direcctionListener);
direction.addActionListener(direcctionListener);
progressBar.setPreferredSize(new Dimension(150, 18));
progressBar.setStringPainted(true);
JPanel topBar = new JPanel(new BorderLayout(5, 0));
topBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
topBar.add(direction, BorderLayout.CENTER);
topBar.add(botonBuscar, BorderLayout.EAST);
JPanel statusBar = new JPanel(new BorderLayout(5, 0));
statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
statusBar.add(labelStatus, BorderLayout.CENTER);
statusBar.add(progressBar, BorderLayout.EAST);
panelTodo.add(topBar, BorderLayout.NORTH);
panelTodo.add(javaFxPanel, BorderLayout.CENTER);
panelTodo.add(statusBar, BorderLayout.SOUTH);
getContentPane().add(panelTodo);
setPreferredSize(new Dimension(1024, 600));
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
}
private void createScene() {
Platform.runLater(() -> {
view = new WebView();
engine = view.getEngine();
engine.setOnAlert((WebEvent<String> wEvent) -> {
System.out.println("JS alert() message: " + wEvent.getData());
});
engine.titleProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Navegador.this.setTitle(newValue);
}
});
}
});
engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
@Override
public void handle(final WebEvent<String> event) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
labelStatus.setText(event.getData());
}
});
}
});
engine.locationProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> ov, String viejoValor, final String nuevoValor) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
direction.setText(nuevoValor);
}
});
}
});
engine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressBar.setValue(newValue.intValue());
}
});
}
});
engine.getLoadWorker().exceptionProperty()
.addListener(new ChangeListener<Throwable>() {
@Override
public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) {
if (engine.getLoadWorker().getState() == FAILED) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//TODO Handling Exception
}
});
}
}
});
javaFxPanel.setScene(new Scene(view));
});
}
public void loadURL(String url) {
Platform.runLater(new Runnable() {
@Override
public void run() {
String urlTemporal = toURL(url);
if (urlTemporal == null) {
urlTemporal = toURL("http://" + url);
}
engine.load(urlTemporal);
}
});
}
private static String toURL(String str) {
try {
return new URL(str).toExternalForm();
} catch (MalformedURLException exception) {
return null;
}
}
}
My problem is that when i open the navigator for the first time it works , but when i close it and then open again it only shows the TextField
and the Button
Notes:
- I use a javaswing button to open the navigator whit the
openNavigator()
method - When i left one Navigator without closing and at the same time i open one or more Navigators it works perfectly
First time I open the Navigator:
Second time I open the Navigator:
Solution
The JavaFX thread/toolkit must be running. Apparently, creating a JFXPanel
is enough to initialize it, but once it is closed the thread is terminated automatically.
To stop it from automatically closing call
Platform.setImplicitExit(false);
so the JavaFX toolkit only closes when the Platform#exit
method is called, or the entire application terminates.
Answered By - Itai