JDK-8088558 : GTK: Filechooser show method sometimes appears to block the JavaFX Application thread
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: 8u20
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2014-06-05
  • Updated: 2018-09-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Description
In Linux if I show a FileChooser from one stage with Platform.runLater() it will appear to block the rendering of ui changes in all of my other stages. Oddly, if I don't use the runLater the other stages keep rendering properly.

Run the test class below and follow these steps:

1. Drag the 2 shown stages apart and click "Show Chooser..." on the first stage.

2. Mouse over the controls on the second stage and observe them responding to the mouse hover.

3. Close the open chooser.

4. Turn on the "Run Later Chooser Show" on the first stage and then click on the "Show Chooser.." button again.

5. Go back to the second stage and observe now that the controls do not respond to mouse hover. The button will respond to you click on it but it is no longer rendering its own updates. The checkbox will not render as selected until you close the chooser blocking the other dialog.

********************************************** Test Class ******************************************************
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

public class ProgressBarBug extends Application { 

   private int stageNum_ = 0; 
   
   @Override public void start(final Stage primaryStage) throws Exception { 
      configureAndShowNewStage(primaryStage);
      configureAndShowNewStage(new Stage());
   } 
   
   private void configureAndShowNewStage( Stage stage ) {
      stage.centerOnScreen(); 
      stage.setHeight(350); 
      stage.setWidth(500); 
      CheckBox checkbox = new CheckBox("Run Later Chooser Show");
      
      Button showModalButton = new Button("Show Chooser...");
      showModalButton.setOnAction(new EventHandler<ActionEvent>() {
         @Override public void handle(ActionEvent event) {
            Runnable runner = new Runnable() {
               @Override public void run() {
                  FileChooser chooser = new FileChooser();
                  chooser.showOpenDialog(stage);
               }
            };
            if ( checkbox.isSelected() ) {
               Platform.runLater(runner);
            } else {
               runner.run();
            }
         }
      });
      
      VBox box = new VBox(30, new Label("Stage #"+ stageNum_), 
            checkbox, showModalButton );
      box.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
      box.setAlignment(Pos.TOP_CENTER);
      stageNum_++;

      stage.setScene( new Scene( new StackPane(box) ) ); 
      stage.show(); 
   }
   
   public static void main(String[] args) throws Exception { 
      launch(args); 
   } 

}
Comments
On a whim I tried mirroring the WinApplication use of the invokeLaterDispatcher in the GTKApplication.staticCommonDialogs_showFileChooser() method and this fixes the issue. @Override protected FileChooserResult staticCommonDialogs_showFileChooser( Window owner, String folder, String filename, String title, int type, boolean multipleMode, ExtensionFilter[] extensionFilters, int defaultFilterIndex) { if (invokeLaterDispatcher != null) { invokeLaterDispatcher.notifyEnteringNestedEventLoop(); } return GtkCommonDialogs.showFileChooser(owner, folder, filename, title, type, multipleMode, extensionFilters, defaultFilterIndex); } Running with this change and 8u40 code, the JavaFX Application thread is no longer blocked when the FileChooser is shown in the test class above. Of course I'm not in the position to say this is the proper fix but I hope you will look at this issue. Currently this GTK FileChooser thread behaviour is inconsistent with the FileChooser in both Windows and OS X. Also with a multi window application it feels very odd for a FileChooser to be effectively application modal. Even worse, this bug means that if a FileChooser is shown with a runLater all animations (ie. progress bars) in other windows freeze since the JavaFX App Thread is essentially blocked.
12-11-2014

I was looking into this bug a little since it causes us grief with out JavaFX application in Linux and I found an interesting difference between the WinApplication implementation and the GTKApplication class. In WinApplication.staticCommonDialogs_showFileChooser() I can see that it uses it's invokeLaterDispatcher to create a "nested" eventloop just before showing the filechooser but this isn't done in the GTKApplication implementation. The same is true in WinApplication.staticCommonDialogs_showFolderChooser(). Is there a good reason for this difference? I'm pretty sure the lack of a nested event loop is the reason we are seeing the GTK Filechooser appear to block the JavaFX Application thread...
11-11-2014