-
Notifications
You must be signed in to change notification settings - Fork 147
Focus issue when using multiple SwingNode on Linux #650
Description
The focus is not correctly managed for Swing controls when there are more than one SwingNode in the same Stage and it is impossible to give the focus to any Swing controls when more than
Steps to reproduce the problem :
- open a stage with two SwingNode, both containing some JTextField
- try to give the focus to the JTextField in the first SwingNode with keyboard or mouse
=> The JTextField can get the focus - try to give the focus to the JTextField in the second SwingNode with keyboard or mouse
=> Problem: it is impossible to give the focus to the JTextField in the second SwingNode - open a second empty Stage within the same application
=> Problem: it is impossible to give the focus to any JTextField in both SwingNode of the primary Stage - Close the second Stage:
=> Problem: it is still impossible to given the focus to any JTexField in both SwingNode of the primary Stage
Observations:
- The problem does not happen on Windows
- No exception raised
- On point 4), there is no need to show the Stage to reproduce the problem (the creation of the Stage without displaying it is enough)
Environment:
- java version: OpenJDK 64-bit 11.0.9.1
- javafx version: OpenJFX 11.0.2
- operating system: Red Hat Linux 8.2
- window manager: Gnome 3.32.2 (classic)
EXAMPLE CODE:
package application;
import java.awt.GridLayout;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SwingNodeFocus extends Application {
private static final AtomicInteger SWING_TEXT_FIELD_ID = new AtomicInteger(0);
private static final AtomicInteger JAVAFX_TEXT_FIELD_ID = new AtomicInteger(0);
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) {
final Pane leftPane = this.createJavafxPane();
final Pane rightPane = this.createJavafxPane();
final Button newStageButton = new Button();
newStageButton.setText("New stage");
newStageButton.setOnAction(evt -> {
final Stage newStage = new Stage();
newStage.initOwner(primaryStage);
newStage.show();
});
primaryStage.setScene(new Scene(new VBox(new HBox(leftPane, rightPane), newStageButton), 400, 200));
primaryStage.show();
}
private Pane createJavafxPane() {
final SwingNode swingNode = this.createSwingNodeWithContent();
final TextField textfield = new TextField();
textfield.setText("JavaFX textfield " + JAVAFX_TEXT_FIELD_ID.getAndIncrement());
return new VBox(swingNode, textfield);
}
private SwingNode createSwingNodeWithContent() {
final SwingNode swingNode1 = new SwingNode();
SwingUtilities.invokeLater(() -> {
swingNode1.setContent(this.createSwingNodeContent());
});
return swingNode1;
}
private JPanel createSwingNodeContent() {
final int nTextFields = 3;
final JPanel panel = new JPanel(new GridLayout(nTextFields, 1));
for (int i = 0; i < nTextFields; i++) {
final JTextField textfield = new JTextField(20);
textfield.setText("Swing textfiled " + SWING_TEXT_FIELD_ID.getAndIncrement());
panel.add(textfield);
}
return panel;
}
}