I am currently evaluating whether it would be feasible to convert my current Swing Application to JavaFX 8 using SwingNode and then slowly change everything to JavaFX components. I have stumbled over two problems, which may be lingering bugs in JavaFX 8, but I can't be sure.
Making JScrollBars non-opaque doesn't seem to work
import java.awt.Color;
import java.awt.GridLayout;
import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Test extends Application {
@Override
public void start(Stage stage) throws Exception {
stage.setMaximized(true);
VBox vbox = new VBox();
MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(new Menu("bla"));
vbox.getChildren().add(menuBar);
StackPane mainPane = new StackPane();
mainPane.setPrefSize(9999, 9999); //Better way to ensure all space used?
vbox.getChildren().add(mainPane);
vbox.setVisible(true);
Scene scene = new Scene(vbox, 9999, 9999); //Better way to ensure all space used?
stage.setScene(scene);
SwingNode swingNode = new SwingNode();
mainPane.getChildren().add(swingNode);
JPanel jPanel = new JPanel();
swingNode.setContent(jPanel); //Seems to interfere with painting of menu
jPanel.setBackground(Color.WHITE);
jPanel.setLayout(new GridLayout(2, 1));
jPanel.add(new JPanel());
JPanel nonOpaquePanel = new JPanel();
nonOpaquePanel.setOpaque(false);
JScrollPane scrollPane = new JScrollPane(nonOpaquePanel);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false); //Black background -> Bug?
jPanel.add(scrollPane);
stage.show();
}
/**
* Main method launching the application.
*/
public static void main(String[] args) {
launch(args);
}
}
Executable jar
Edit: I edited my example to use the EDT for creating the Swing components. That didn't change anything. Or am I doing something wrong?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class Test extends Application {
private JPanel jPanel = null;
@Override
public void start(Stage stage) throws Exception {
if (Platform.isFxApplicationThread()) { // all of this happens on the fx application thread
stage.setMaximized(true);
VBox vbox = new VBox();
MenuBar menuBar = new MenuBar();
menuBar.getMenus().add(new Menu("bla"));
vbox.getChildren().add(menuBar);
StackPane mainPane = new StackPane();
mainPane.setPrefSize(9999, 9999); //Better way to ensure all space used?
vbox.getChildren().add(mainPane);
vbox.setVisible(true);
Scene scene = new Scene(vbox, 9999, 9999); //Better way to ensure all space used?
stage.setScene(scene);
SwingNode swingNode = new SwingNode();
mainPane.getChildren().add(swingNode);
SwingUtilities.invokeLater(new Runnable() { //Use EDT to build swing components
@Override
public void run() {
jPanel = new JPanel();
jPanel.setBackground(Color.WHITE);
jPanel.setLayout(new GridLayout(2, 1));
jPanel.add(new JPanel());
JLabel nonOpaquePanel = new JLabel("Bla");
nonOpaquePanel.setPreferredSize(new Dimension(5000, 5000));
nonOpaquePanel.setOpaque(false);
JScrollPane scrollPane = new JScrollPane(nonOpaquePanel);
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false); //Black background -> Bug?
jPanel.add(scrollPane);
}
});
Thread.sleep(1000); //terrible way to wait for the EDT, I know
swingNode.setContent(jPanel); //Seems to interfere with painting of menu
stage.show();
SwingUtilities.invokeLater(new Runnable() { //I am pretty sure this isn't necessary, but whatever
@Override
public void run() {
jPanel.repaint();
}
});
}
}
/**
* Main method launching the application.
*/
public static void main(String[] args) {
launch(args);
}
}
JavaFX SDK provides the JFXPanel class, which is located in the javafx. embed. swing package and enables you to embed JavaFX content into Swing applications.
Originally distributed as a separately downloadable library, Swing has been included as part of the Java Standard Edition since release 1.2. The Swing classes and components are contained in the javax.
Is JavaFX replacing Swing as the new client UI library for Java SE? Yes. However, Swing will remain part of the Java SE specification for the foreseeable future, and therefore included in the JRE.
JavaFX for Oracle Java 8 is not a separate installation. JavaFX is included in Oracle JDK 8 running on OS X, Linux x86 and Windows.
JavaFX even contains a WebView supported by the popular WebKit browser; therefore, you’ll be able to introduce websites or net applications within JavaFX. What is Swing? Swing API may be a set of extendable GUI parts to ease the developer’s life to form JAVA primarily based Front End/GUI Applications.
As of version 7.2, the NetBeans IDE provides support for Swing applications with the embedded JavaFX content. When creating a new project, in the JavaFX category choose JavaFX in Swing Application. To run this application from behind a firewall, you must specify proxy settings in order for the application to access a remote resource.
With JavaFX and Swing data coexisting in a single application, you may encounter the following interoperability situations: A JavaFX data change is triggered by a change in Swing data. A Swing data change is triggered by a change in JavaFX data. Changing JavaFX Data in Response to a Change in Swing Data.
"Incompatibilities between JDK 8 and JDK 7" "Features Removed from Java SE 8" "Features Removed from JDK 8" "Deprecated APIs" The following compatibility documents track incompatibility between adjacent Java versions. For example, this compatibility page reports only Java SE 8 incompatibilities with Java SE 7, and not with previous versions.
Try wrapping your update code in this when you make an update call. This code has helped me before on other projects.
Platform.runLater(new Runnable() {
@Override
public void run() {
// Update the text node with calculated results
}
});
Source
You can use -Djavafx.embed.singleThread=true
, so you dont have to make the event dispatching on your own.
JavaFx APIDesign
Must have been a bug in JavaFX, this very example is working fine now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With