ADDITIONAL SYSTEM INFORMATION :
Found the problem using:
Mac OS Mojave version 10.14.5
Java OpenJDK 12.0.1 and OpenJDK 11
JavaFX 12.0.1 and JavaFX 11
A DESCRIPTION OF THE PROBLEM :
I have a locking problem with my Java application on MacOS where I am using the WebView in a Java Swing application. I am wrapping the WebView within the JFXPanel. The problem occurs when I switch focus from one my Swing Application to another window and then regain focus to my Swing Application.
It then appears to lock and it appears that the AWT-EventThread is waiting within a FutureTask:
Unsafe.park(boolean, long) line: not available [native method]
LockSupport.park(Object) line: 194
FutureTask<V>.awaitDone(boolean, long) line: 447
FutureTask<V>.get() line: 190
InputMethodClientlmpl.getTextLocation(int) line: 137
SceneSInputMethodRequestsDelegate.getTextLocation(int) line: 4117
InputMethodSupportSInputMethodRequestsAdapter.getTextLocation(TextHitInfo) line: 61
InputMethodContext.getTextLocation(TextHitInfo) line: 278
ClInputMethod$6.run(Q line: 722
InvocationEvent.dispatch() line: 303
EventQueue.dispatchEventlmpl(AWTEvent, Object) line: 770
EventQueue$4.run( line: 721
EventQueue$4.run() line: 715
AccessController.executePrivileged(PrivilegedAction<T>, AccessControlContext, Class<?>) line: 750
AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 389
ProtectionDomainSJavaSecurityAccessimpl.dolntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) li:
ProtectionDomainSJavaSecurityAccessimpl.dolntersectionPrivilege(PrivilegedAction<T>, AccessControlContext) line: 95
EventQueue$5.runQ) line: 745
EventQueue$5.run(Q line: 743
AccessController.executePrivileged(PrivilegedAction<T>, AccessControlContext, Class<?>) line: 750
AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: 389
ProtectionDomainSJavaSecurityAccessimpl.dolntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) lit
EventQueue.dispatchEvent(AWTEvent) line: 742
EventDispatchThread.pumpOneEventForFilters(int) line: 203
EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter) line: 124
EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component) line: 113 v
I cannot do anything else with the application.
I have only found this problem on Mac OS and I cannot replicate it in Linux or Windows OS.
I have only noticed this problem when losing focus form the application and regaining focus. Otherwise the WebView works as expected.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Reproduced by implementing the example SimpleSwingBrowser example from Oracle:
https://docs.oracle.com/javafx/2/swing/SimpleSwingBrowser.java.htm
Run the Swing application on the MacOS and lose focus to another window on the mac.. e.g TextEdit or Safari.
Regaining focus back the the Swing Application it just hangs and you cannot click on anything or do anything.
My application does exactly the same, but this simple example replicates my problem.
Note that Windows and Linux work perfectly well.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Can click on the browser and follow links.
ACTUAL -
The application is locked and I cannot press on any links and the busy cursor is shown. The application never resolves itself.
---------- BEGIN SOURCE ----------
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.MalformedURLException;
import java.net.URL;
import static javafx.concurrent.Worker.State.FAILED;
public class SimpleSwingBrowser extends JFrame {
private final JFXPanel jfxPanel = new JFXPanel();
private WebEngine engine;
private final JPanel panel = new JPanel(new BorderLayout());
private final JLabel lblStatus = new JLabel();
private final JButton btnGo = new JButton("Go");
private final JTextField txtURL = new JTextField();
private final JProgressBar progressBar = new JProgressBar();
public SimpleSwingBrowser() {
super();
initComponents();
}
private void initComponents() {
createScene();
ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadURL(txtURL.getText());
}
};
btnGo.addActionListener(al);
txtURL.addActionListener(al);
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(txtURL, BorderLayout.CENTER);
topBar.add(btnGo, BorderLayout.EAST);
JPanel statusBar = new JPanel(new BorderLayout(5, 0));
statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
statusBar.add(lblStatus, BorderLayout.CENTER);
statusBar.add(progressBar, BorderLayout.EAST);
panel.add(topBar, BorderLayout.NORTH);
panel.add(jfxPanel, BorderLayout.CENTER);
panel.add(statusBar, BorderLayout.SOUTH);
getContentPane().add(panel);
setPreferredSize(new Dimension(1024, 600));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
private void createScene() {
Platform.runLater(new Runnable() {
@Override
public void run() {
WebView view = new WebView();
engine = view.getEngine();
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() {
SimpleSwingBrowser.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() {
lblStatus.setText(event.getData());
}
});
}
});
engine.locationProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
txtURL.setText(newValue);
}
});
}
});
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>() {
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() {
JOptionPane.showMessageDialog(
panel,
(value != null) ?
engine.getLocation() + "\n" + value.getMessage() :
engine.getLocation() + "\nUnexpected error.",
"Loading error...",
JOptionPane.ERROR_MESSAGE);
}
});
}
}
});
jfxPanel.setScene(new Scene(view));
}
});
}
public void loadURL(final String url) {
Platform.runLater(new Runnable() {
@Override
public void run() {
String tmp = toURL(url);
if (tmp == null) {
tmp = toURL("http://" + url);
}
engine.load(tmp);
}
});
}
private static String toURL(String str) {
try {
return new URL(str).toExternalForm();
} catch (MalformedURLException exception) {
return null;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SimpleSwingBrowser browser = new SimpleSwingBrowser();
browser.setVisible(true);
browser.loadURL("http://oracle.com");
}
});
}
}
---------- END SOURCE ----------
FREQUENCY : always