Ответ 1
Должна быть ошибка в JavaFX, этот пример сейчас работает нормально.
В настоящее время я оцениваю, возможно ли преобразовать текущее Swing-приложение в JavaFX 8 с помощью SwingNode, а затем медленно изменить все на компоненты JavaFX. Я столкнулся с двумя проблемами, которые могут быть затяжными ошибками в JavaFX 8, но я не могу быть уверен.
Сделать JScrollBars непрозрачным, похоже, не работает
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);
}
}
Изменить: Я редактировал свой пример, чтобы использовать EDT для создания компонентов Swing. Это ничего не изменило. Или я делаю что-то неправильно?
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, этот пример сейчас работает нормально.
Попробуйте обернуть код обновления в этом случае при вызове обновления. Этот код помог мне раньше в других проектах.
Platform.runLater(new Runnable() {
@Override
public void run() {
// Update the text node with calculated results
}
});
Вы можете использовать -Djavafx.embed.singleThread=true
, поэтому вам не нужно выполнять отправку событий самостоятельно.