Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8233181

HighDPI Scaling Bug On Linux With JavaFX Interoperability With SWT

XMLWordPrintable

    • x86_64
    • linux

      ADDITIONAL SYSTEM INFORMATION :
      Tested on Ubuntu 64-bit 19.04, 19.10, Mint, Fedora with Gnome and KDE.
      Scaling factor 2 was enabled.
      Using OpenJDK 11,12,13 Linux 64-bit.

      A DESCRIPTION OF THE PROBLEM :
      I already posted this possible bug to the Eclipse bug database:
      https://bugs.eclipse.org/bugs/show_bug.cgi?id=546011

      The bug occurs if you embedd JavaFX in SWT and only on Linux with a HighDPI display (or scale factor 2 on GNOME and maybe KDE).

      Somehow the JavaFX scale settings interfere with SWT. The behaviour can be reproduced with the following simple SWT/JavaFX example (scale factor on Ubuntu Gnome = 2):

      https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/fx-swt_interoperability.htm

      If you execute this simple example the buttons are not scaled at all. If you press on the JavaFX button only the SWT button gets resized.

      Already in this very simple example the SWT JavaFX interop. seems to be disturbed. The example was ,e.g., tested with Ubuntu Linux 19.04 installed.

      In the Eclipse bug database a screenshot is available, too which shows the result with an RCP application embedding JavaFX in SWT.

      The bug occurs with OpenJFX 11,12,13

      This behaviour can't be reproduced with Java 1.8.x (with no scaling support).

      REGRESSION : Last worked in version 13

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      With the following example the bug can be reproduced on different Linux distributions.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The application scales on Linux highDPI displays. Both SWT and JavaFX components will scale.
      ACTUAL -
      If you execute this simple example the buttons are not scaled at all. If you press on the JavaFX button only the SWT button gets resized.

      ---------- BEGIN SOURCE ----------
      import javafx.embed.swt.FXCanvas;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.scene.Group;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.paint.Color;
       
      import org.eclipse.swt.SWT;
      import org.eclipse.swt.graphics.Point;
      import org.eclipse.swt.layout.RowLayout;
      import org.eclipse.swt.widgets.Display;
      import org.eclipse.swt.widgets.Event;
      import org.eclipse.swt.widgets.Listener;
      import org.eclipse.swt.widgets.Shell;
       
      public class TwoButtons {
       
          public static void main(String[] args) {
              final Display display = new Display();
              final Shell shell = new Shell(display);
              final RowLayout layout = new RowLayout();
              shell.setLayout(layout);
       
              /* Create the SWT button */
              final org.eclipse.swt.widgets.Button swtButton =
                      new org.eclipse.swt.widgets.Button(shell, SWT.PUSH);
              swtButton.setText("SWT Button");
       
              /* Create an FXCanvas */
              final FXCanvas fxCanvas = new FXCanvas(shell, SWT.NONE) {
                  
                      @Override
                      public Point computeSize(int wHint, int hHint, boolean changed) {
                      getScene().getWindow().sizeToScene();
                      int width = (int) getScene().getWidth();
                      int height = (int) getScene().getHeight();
                      return new Point(width, height);
                  }
              };
              /* Create a JavaFX Group node */
              Group group = new Group();
              /* Create a JavaFX button */
              final Button jfxButton = new Button("JFX Button");
              /* Assign the CSS ID ipad-dark-grey */
              jfxButton.setId("ipad-dark-grey");
              /* Add the button as a child of the Group node */
              group.getChildren().add(jfxButton);
              /* Create the Scene instance and set the group node as root */
              Scene scene = new Scene(group, Color.rgb(
                      shell.getBackground().getRed(),
                      shell.getBackground().getGreen(),
                      shell.getBackground().getBlue()));
              /* Attach an external stylesheet */
              scene.getStylesheets().add("twobuttons/Buttons.css");
              fxCanvas.setScene(scene);
       
              /* Add Listeners */
              swtButton.addListener(SWT.Selection, new Listener() {
       
                  @Override
                  public void handleEvent(Event event) {
                      jfxButton.setText("JFX Button: Hello from SWT");
                      shell.layout();
                  }
              });
              jfxButton.setOnAction(new EventHandler<ActionEvent>() {
       
                  @Override
                  public void handle(ActionEvent event) {
                      swtButton.setText("SWT Button: Hello from JFX");
                      shell.layout();
                  }
              });
       
              shell.open();
              while (!shell.isDisposed()) {
                  if (!display.readAndDispatch()) {
                      display.sleep();
                  }
              }
              display.dispose();
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


            tschindl Tom Schindl
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: