Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting from Swing to JavaFX?

When converting a Swing project to a JavaFx project, which classes from JavaFx match up to the Swing classes?

A 1-1 matchup is best.

I am not looking for integration with Swing, but a complete makeover.

like image 784
gagarwa Avatar asked Mar 10 '16 03:03

gagarwa


2 Answers

The following are some of the basic classes:

  • Swing -> JavaFx
  • JFrame -> Application & Stage (if you extend JFrame in your main class, Application.launch() can be used to launch one that extends Application). Stage is explicitly JavaFx and necessary for creating a Window. You will need to use an instance of it, rather than an instance of JFrame.
  • JPanel -> Scene & Pane (Scene matches up with JPanel, but your classes should extend Pane. Then build a scene from the pane. Pane's are layouts in JavaFX)
  • JButton -> Button
  • JLabel -> Label
  • In many cases, removing the J will do the trick...
  • JOptionPane -> Dialog (but, not always)
  • ActionListener -> EventHandler< ActionEvent >) (Need to create a new method/class in JavaFx for each action that you need, unlike Swing's one method does all)

UPDATE Using event handlers should be easier now with Java 8+, with the added capability of functional interfaces, which JavaFX now supports.

Example Swing (the basic interface for a game I made)

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 Example (Almost the same example in 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);
        }

    }

}

}

Warning: some of the matchups may not be ideal with the essence of JavaFx, but they will do the work

Note: To use FX properly, it is suggested to use FXML and/or SceneBuilder.

like image 181
gagarwa Avatar answered Sep 19 '22 10:09

gagarwa


I am not sure if it helps during converting, but I found that using SceneBuilder and fxmls makes building JavaFX apps much easier. Mainly, controller classes need to be added, view is built in .fxml . Just maybe it will be easier to build app from scratch in SceneBuilder, than tediously converting?

like image 43
Mykola Avatar answered Sep 22 '22 10:09

Mykola