Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFx SwingNode - Displays Black, Background, or Component Randomly

I am having a problem with JavaFx's SwingNode showing the components it holds in Java 1.8.0_102-b14. I am not sure if this issue is due to my Java version being old, a bug within the current (if mine is current) Java release, or some SwingNode process I am doing incorrectly. I know this issue has been reported before JavaFX and SwingNode - partial black Window so I am really looking for feedback on my Java version.

This code will usually display "button1" wrong, as in black or the background color, until the mouse hovers over it or it is clicked. This is not an ideal workaround for me as my project using much more complex swing panels in the Fx project and pure Fx is not an option unfortunately.

import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import javax.swing.JButton;

public class Test extends Application {

  @Override
  public void start(Stage stage) {
      final SwingNode swingNode1 = new SwingNode();
      final SwingNode swingNode2 = new SwingNode();

      swingNode2.setContent(new JButton("Click me!"+2));
      swingNode1.setContent(new JButton("Click me!"+1));

      BorderPane pane = new BorderPane();
      pane.setLeft(swingNode1);
      pane.setRight(swingNode2);

      stage.setScene(new Scene(pane, 200, 50));
      stage.show();
  }

  public static void main(String[] args) {
      launch(args);
  }
}

In creating this sssce I found that setting the content in the left SwingNode before setting the content in the right SwingNode corrected the issue for this simple code, but not for my larger project. So I am guessing it is a memory leak, but I can't tell from my machine.

Can someone test this code and see if they get similar results?

Edit: Thanks for the quick feedback, please don't focus on the buttons as they are merely a tool to demonstrate my problem. The weird functionality acts in the same way with other objects rather than buttons.

like image 941
Lost Avatar asked Feb 07 '23 08:02

Lost


1 Answers

You must create and display Swing components on the AWT Event Dispatch thread (see Swing's threading policy). The Application.start() method is invoked on the FX Application Thread.

Thus you need

public class Test extends Application {

  @Override
  public void start(Stage stage) {
      final SwingNode swingNode1 = new SwingNode();
      final SwingNode swingNode2 = new SwingNode();

      SwingUtilities.invokeLater(() -> {
          swingNode2.setContent(new JButton("Click me!"+2));
          swingNode1.setContent(new JButton("Click me!"+1));
      });

      BorderPane pane = new BorderPane();
      pane.setLeft(swingNode1);
      pane.setRight(swingNode2);

      stage.setScene(new Scene(pane, 200, 50));
      stage.show();
  }

  public static void main(String[] args) {
      launch(args);
  }
}
like image 161
James_D Avatar answered Feb 17 '23 03:02

James_D