【问题标题】:Converting from Swing to JavaFX? (Migration Guide)从 Swing 转换为 JavaFX?
【发布时间】:2016-06-24 17:23:01
【问题描述】:

将 Swing 项目转换为 JavaFx 项目时,JavaFx 中的哪些类与 Swing 类匹配?

1-1 对决是最好的。

我不是在寻找与 Swing 的集成,而是彻底改造。

【问题讨论】:

    标签: java swing graphics javafx


    【解决方案1】:

    以下是一些基本类:

    • Swing -> JavaFx
    • JFrame -> Application & Stage(如果您在主类中扩展 JFrame,Application.launch() 可用于启动扩展 Application)。 Stage 是明确的 JavaFx 并且是创建 Window 所必需的。您将需要使用它的实例,而不是 JFrame 的实例。
    • JPanel -> Scene & Pane(场景与 JPanel 匹配,但您的类应该扩展 Pane。然后从窗格构建场景。窗格是 JavaFX 中的布局)
    • JButton -> 按钮
    • JLabel -> 标签
    • 在许多情况下,删除 J 即可解决问题...
    • JOptionPane -> 对话框(但并非总是如此)
    • ActionListener -> EventHandler)(需要在 JavaFx 中为您需要的每个操作创建一个新方法/类,不像 Swing 的一个方法可以完成所有工作)

    更新现在使用 Java 8+ 应该更容易使用事件处理程序,并增加了 JavaFX 现在支持的函数式接口功能。

    示例 Swing(我制作的游戏的基本界面)

    public class Interface extends JFrame {
    
    public static void main(String[] args) {
        new Interface();
    }
    
    private CardLayout layout;
    private JPanel manager;
    private Introduction start;
    private MainDisplay display;
    
    public Interface() {
        super("Demo");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setMinimumSize(new Dimension(750, 500));
        this.setPreferredSize(new Dimension(750, 500));
        this.setMaximumSize(new Dimension(750, 500));
    
        setUp();
    
        this.pack();
        this.setVisible(true);
    }
    
    private void setUp() {
        layout = new CardLayout();
        manager = new JPanel(layout);
        this.add(manager);
    
        start = new Introduction();
        manager.add(start, INTRODUCTION);
    
        display = new MainDisplay();
        manager.add(display);
    
        layout.show(manager);
    }
    
    public class Introduction extends JPanel implements ActionListener {
    
        private static final int LOAD = 0;
        private static final int SAVE = 1;
        private JButton start;
        private JButton toGame;
        private JButton load;
        private JButton save;
        private JButton exit;
    
        public Introduction() {
            setUp();
        }
    
        private void setUp() {
            SpringLayout manager = new SpringLayout();
            this.setLayout(manager);
    
            JLabel title = new JLabel("Demo");
            title.setFont(new Font(Font.SERIF, Font.BOLD, 60));
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, title, 0,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, title, 10, SpringLayout.NORTH,
                    this);
            this.add(title);
    
            start = new JButton("New Game");
            start.setFont(new Font(Font.SERIF, Font.PLAIN, 16));
            start.addActionListener(this);
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, start, -250,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, start, 50, SpringLayout.SOUTH,
                    title);
            this.add(start);
    
            toGame = new JButton("Continue");
            toGame.setFont(new Font(Font.SERIF, Font.PLAIN, 16));
            toGame.addActionListener(this);
            toGame.setEnabled(false);
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, toGame, -250,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, toGame, 10, SpringLayout.SOUTH,
                    start);
            this.add(toGame);
    
            load = new JButton("Load Game");
            load.setFont(new Font(Font.SERIF, Font.PLAIN, 16));
            load.addActionListener(this);
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, load, -250,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, load, 10, SpringLayout.SOUTH,
                    toGame);
            this.add(load);
    
            save = new JButton("Save Game");
            save.setFont(new Font(Font.SERIF, Font.PLAIN, 16));
            save.addActionListener(this);
            save.setEnabled(false);
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, save, -250,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, save, 10, SpringLayout.SOUTH, load);
            this.add(save);
    
            exit = new JButton("Exit Game");
            exit.setFont(new Font(Font.SERIF, Font.PLAIN, 16));
            exit.setToolTipText("Saves the current game, and exits the program.");
            exit.addActionListener(this);
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, exit, -250,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, exit, 10, SpringLayout.SOUTH, save);
            this.add(exit);
        }
    
        private void perform(int option) {
            JFileChooser chooser = new JFileChooser();
            chooser.setFileFilter(new TextFileFilter());
            if (option == LOAD) {
                int choice = chooser.showDialog(this, "Load Game");
                if (choice == JFileChooser.APPROVE_OPTION)
                    chooser.getSelectedFile();
            } else if (option == SAVE) {
                int choice = chooser.showDialog(this, "Save Game");
                if (choice == JFileChooser.APPROVE_OPTION)
                    chooser.getSelectedFile();
            }
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            if (display.isRunning()) {
                if (e.getSource() == start || e.getSource() == load) {
                    String verify = "A game is currently running.  Are you sure you want to start a new game?"
                            + "\r\nAny previous game data will be deleted.";
                    int choice = JOptionPane.showConfirmDialog(this, verify,
                            "New Game - Warning", JOptionPane.YES_NO_OPTION,
                            JOptionPane.WARNING_MESSAGE);
    
                    if (choice == JOptionPane.NO_OPTION)
                        return;
                }
            }
    
            if (e.getSource() == start) {
                display.start();
                layout.show(manager, MAIN_DISPLAY);
                toGame.setEnabled(true);
                save.setEnabled(true);
            } else if (e.getSource() == toGame)
                layout.show(manager, MAIN_DISPLAY);
            else if (e.getSource() == load)
                perform(LOAD);
            else if (e.getSource() == save)
                perform(SAVE);
            else if (e.getSource() == exit) {
                perform(SAVE);
                Interface.this.setVisible(false);
                Interface.this.dispose();
            }
        }
    
    }
    
    public class MainDisplay extends JPanel implements ActionListener {
    
        private static final long serialVersionUID = 1L;
        private boolean running;
        private JButton overview;
        private JButton map;
        private JButton ranking;
        private JButton reports;
        private JButton home;
    
        public MainDisplay() {
            running = false;
            setUp();
        }
    
        public boolean isRunning() {
            return running;
        }
    
        private void setUp() {
            SpringLayout manager = new SpringLayout();
            this.setLayout(manager);
    
            ranking = new JButton("Ranking");
            ranking.setFont(new Font(Font.SERIF, Font.PLAIN, 10));
            ranking.addActionListener(this);
            manager.putConstraint(SpringLayout.HORIZONTAL_CENTER, ranking, 0,
                    SpringLayout.HORIZONTAL_CENTER, this);
            manager.putConstraint(SpringLayout.NORTH, ranking, 10, SpringLayout.NORTH,
                    this);
            this.add(ranking);
    
            map = new JButton("Map");
            map.setFont(new Font(Font.SERIF, Font.PLAIN, 10));
            map.addActionListener(this);
            manager.putConstraint(SpringLayout.EAST, map, -10, SpringLayout.WEST,
                    ranking);
            manager.putConstraint(SpringLayout.NORTH, map, 10, SpringLayout.NORTH, this);
            this.add(map);
    
            overview = new JButton("Overview");
            overview.setFont(new Font(Font.SERIF, Font.PLAIN, 10));
            overview.addActionListener(this);
            manager.putConstraint(SpringLayout.EAST, overview, -10, SpringLayout.WEST,
                    map);
            manager.putConstraint(SpringLayout.NORTH, overview, 10, SpringLayout.NORTH,
                    this);
            this.add(overview);
    
            reports = new JButton("Reports");
            reports.setFont(new Font(Font.SERIF, Font.PLAIN, 10));
            reports.addActionListener(this);
            manager.putConstraint(SpringLayout.WEST, reports, 10, SpringLayout.EAST,
                    ranking);
            manager.putConstraint(SpringLayout.NORTH, reports, 10, SpringLayout.NORTH,
                    this);
            this.add(reports);
    
            home = new JButton("Home");
            home.setFont(new Font(Font.SERIF, Font.PLAIN, 10));
            home.addActionListener(this);
            manager.putConstraint(SpringLayout.WEST, home, 10, SpringLayout.EAST,
                    reports);
            manager.putConstraint(SpringLayout.NORTH, home, 10, SpringLayout.NORTH, this);
            this.add(home);
        }
    
        public void start() {
            running = true;
        }
    
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == home) {
                layout.show(manager, INTRODUCTION);
            }
        }
    
    }
    
    public static final class TextFileFilter extends FileFilter {
    
        private static final String FILE_EXTENSION = "tra";
    
        @Override
        public boolean accept(File f) {
            if (f.isDirectory())
                return true;
            if (f.getName().toLowerCase().endsWith(FILE_EXTENSION))
                return true;
            return false;
        }
    
        @Override
        public String getDescription() {
            return "Demo";
        }
    }
    
    }
    

    JavaFx 示例(JavaFx 中的示例几乎相同)

    public class Interface extends Application {
    
    public static void main(String[] args) {
        Application.launch(Interface.class, args);
    }
    
    private static final int WIDTH = 750;
    private static final int HEIGHT = 500;
    private static Stage stage;
    private static Introduction start;
    private static MainDisplay display;
    private static Scene startScene;
    private static Scene displayScene;
    
    public Interface() {
        start = new Introduction();
        display = new MainDisplay();
        startScene = new Scene(start, WIDTH, HEIGHT);
        displayScene = new Scene(display, WIDTH, HEIGHT);
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        Interface.stage = primaryStage;
    
        stage.setTitle(Constants.TITLE);
        stage.setResizable(false);
        stage.setWidth(WIDTH);
        stage.setHeight(HEIGHT);
    
        stage.setScene(startScene);
        stage.show();
    }
    
    public class Introduction extends BorderPane {
    
        private static final int LOAD = 0;
        private static final int SAVE = 1;
        private Button toGame;
        private Button save;
        public Introduction() {
            setUp();
        }
    
        private void setUp() {
    
            this.setBackground(
                    new Background(new BackgroundFill(Color.BLACK, null, null)));
    
            VBox menu = new VBox();
            menu.setSpacing(10);
    
            Label title = new Label(Constants.TITLE.toUpperCase());
            title.setFont(Font.font("Arial", FontWeight.THIN, 60));
            title.setTextFill(Color.RED);
            menu.getChildren().add(title);
    
            int btnWidth = 300;
            Background menuBkg = new Background(new BackgroundFill(null, null, null));
            Border menuBorder = new Border(new BorderStroke(Color.RED,
                    BorderStrokeStyle.SOLID, new CornerRadii(10), null));
    
            Button start = new Button(Constants.START.toUpperCase());
            start.setFont(Font.font("Times New Roman", 16));
            start.setTextFill(Color.WHITE);
            start.setPrefWidth(btnWidth);
            start.setBackground(menuBkg);
            start.setBorder(menuBorder);
            start.setOnAction(new StartHandler());
    
            toGame = new Button(Constants.CONTINUE.toUpperCase());
            toGame.setFont(Font.font("Times New Roman", 16));
            toGame.setTextFill(Color.WHITE);
            toGame.setPrefWidth(btnWidth);
            toGame.setBackground(menuBkg);
            toGame.setBorder(menuBorder);
            toGame.setDisable(true);
            toGame.setOnAction(new ContinueHandler());
    
            Button load = new Button(Constants.LOAD.toUpperCase());
            load.setFont(Font.font("Times New Roman", 16));
            load.setTextFill(Color.WHITE);
            load.setPrefWidth(btnWidth);
            load.setBackground(menuBkg);
            load.setBorder(menuBorder);
            load.setOnAction(new LoadHandler());
    
            save = new Button(Constants.SAVE.toUpperCase());
            save.setFont(Font.font("Times New Roman", 16));
            save.setTextFill(Color.WHITE);
            save.setPrefWidth(btnWidth);
            save.setBackground(menuBkg);
            save.setBorder(menuBorder);
            save.setDisable(true);
            save.setOnAction(new SaveHandler());
    
            Button ranking = new Button(Constants.RANKING.toUpperCase());
            ranking.setFont(Font.font("Times New Roman", 16));
            ranking.setTextFill(Color.WHITE);
            ranking.setPrefWidth(btnWidth);
            ranking.setBackground(menuBkg);
            ranking.setBorder(menuBorder);
            ranking.setOnAction(new RankingHandler());
    
            Button exit = new Button(Constants.EXIT.toUpperCase());
            exit.setFont(Font.font("Times New Roman", 16));
            exit.setTextFill(Color.WHITE);
            exit.setPrefWidth(btnWidth);
            exit.setBackground(menuBkg);
            exit.setBorder(menuBorder);
            exit.setTooltip(new Tooltip(Constants.EXIT_TOOLTIP));
            exit.setOnAction(new ExitHandler());
    
            menu.getChildren().addAll(start, toGame, load, save, ranking, exit);
            menu.setAlignment(Pos.CENTER);
            this.setCenter(menu);
        }
    
        private void performIO(int option) {
            FileChooser chooser = new FileChooser();
            ExtensionFilter ext = new ExtensionFilter(Constants.EXT_DESCRIPTION, ".pt");
            chooser.setSelectedExtensionFilter(ext);
            if (option == LOAD) {
                chooser.setTitle(Constants.LOAD);
                File choice = chooser.showOpenDialog(stage);
            } else if (option == SAVE) {
                chooser.setTitle(Constants.SAVE);
                File choice = chooser.showSaveDialog(stage);
            }
        }
    
        private boolean verifyRestart() {
            Alert alert = new Alert(AlertType.WARNING, Constants.START_WARNING_MESSAGE,
                    ButtonType.YES, ButtonType.NO);
            alert.setTitle(Constants.START_WARNING);
            alert.showAndWait();
    
            if (alert.getResult() == ButtonType.YES)
                return true;
            return false;
        }
    
        private class StartHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                if (display.isRunning()) {
                    if (!verifyRestart())
                        return;
                }
    
                display.start();
                stage.setScene(displayScene);
                toGame.setDisable(false);
                save.setDisable(false);
            }
    
        }
    
        private class ContinueHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                stage.setScene(displayScene);
            }
    
        }
    
        private class LoadHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                if (display.isRunning()) {
                    if (!verifyRestart())
                        return;
                }
    
                performIO(LOAD);
            }
    
        }
    
        private class SaveHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                performIO(SAVE);
            }
    
        }
    
        private class RankingHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                stage.setScene(displayScene);
            }
    
        }
    
        private class ExitHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                performIO(SAVE);
                Platform.exit();
            }
    
        }
    
    }
    
    public static class MainDisplay extends AnchorPane {
    
        private boolean running;
    
        public MainDisplay() {
            running = false;
            tower = new Tower();
            setUp();
        }
    
        private void setUp() {
            Color blue = new Color(34 / 255, 37 / 255, 47 / 255, 1.0);
    
            this.setBackground(new Background(new BackgroundFill(blue, null, null)));
    
            Background bkg = new Background(new BackgroundFill(null, null, null));
            Border menuBorder = new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID,
                    new CornerRadii(10), null));
    
            Button home = new Button(Constants.HOME);
            home.setFont(Font.font("Times New Roman", 10));
            home.setTextFill(Color.WHITE);
            home.setBackground(bkg);
            home.setBorder(menuBorder);
            home.setOnAction(new HomeHandler());
            this.getChildren().add(home);
            AnchorPane.setTopAnchor(home, 10.0);
            AnchorPane.setRightAnchor(home, 10.0);
        }
    
        public void start() {
            running = true;
        }
    
        public boolean isRunning() {
            return running;
        }
    
        private class HomeHandler implements EventHandler<ActionEvent> {
    
            @Override
            public void handle(ActionEvent event) {
                stage.setScene(startScene);
            }
    
        }
    
    }
    
    }
    

    警告:有些对局可能不符合 JavaFx 的精髓,但它们会发挥作用

    注意:要正确使用FX,建议使用FXML和/或SceneBuilder

    【讨论】:

      【解决方案2】:

      我不确定它在转换过程中是否有帮助,但我发现使用 SceneBuilder 和 fxmls 可以更轻松地构建 JavaFX 应用程序。主要是需要添加控制器类,视图内置在 .fxml 中。 也许在 SceneBuilder 中从头开始构建应用程序比繁琐的转换更容易?

      【讨论】:

      • 正如我在最后提到的,直接转换可能并不理想,但对于新用户来说它可能会有所帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-29
      相关资源
      最近更新 更多