2

Disclaimer: I am very new to Java, but I've been building .NET applications for 13 years.

I'm trying to build this Java application that does some basic calculations for tutoring. It's honestly not that big of a program, but I can't even get it to the Hello, World! state! I have a requirement that's making it difficult:

GUI should be built using javax.swing components jButton, jLabel, jTextField, jTextArea, jFrame, and jPanel.

So, I downloaded NetBeans 7.3 and created a JavaFX in Swing application. The default code obviously works but it uses Button instead of JButton:

private void createScene() {
    Button btn = new Button();
    btn.setText("Say 'Hello World'");
    btn.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            System.out.println("Hello World!");
        }
    });
    StackPane root = new StackPane();
    root.getChildren().add(btn);
    fxContainer.setScene(new Scene(root));
}

so I when I change it to use a JButton I have to also change the type the root is built from. While banging my head against the wall I found an example here (not directly related) that used the JRootPane and I thought that might work in place of the StackPane. So I refactored the code like this:

private void createScene() {
    JButton btn = new JButton();
    btn.setText("Say 'Hello World'");
    JRootPane root = new JRootPane();
    root.getContentPane().add(btn);
    fxContainer.setScene(new Scene(root));
}

and that code is fine except for fxContainer.setScene(new Scene(root)); because root isn't a Parent.

FYI, the application class implements JApplet and has a main and init that looks like this:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
            } catch (Exception e) {
            }
            
            JFrame frame = new JFrame("Tutoring Calculator");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            JApplet applet = new TutoringCalculator();
            applet.init();
            
            frame.setContentPane(applet.getContentPane());
            
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            
            applet.start();
        }
    });
}

@Override
public void init() {
    fxContainer = new JFXPanel();
    fxContainer.setPreferredSize(new Dimension(JFXPANEL_WIDTH_INT, JFXPANEL_HEIGHT_INT));
    add(fxContainer, BorderLayout.CENTER);
    // create JavaFX scene
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            createScene();
        }
    });
}

How can I fulfill the requirement stated above? Am I really going about this whole thing the wrong way?

SSCCE

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tutoringcalculator;

import java.awt.BorderLayout;
import java.awt.Dimension;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

/**
 *
 * @author Owner
 */
public class TutoringCalculator extends JApplet {
    
    private static final int JFXPANEL_WIDTH_INT = 300;
    private static final int JFXPANEL_HEIGHT_INT = 250;
    private static JFXPanel fxContainer;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception e) {
                }
                
                JFrame frame = new JFrame("Tutoring Calculator");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                
                JApplet applet = new TutoringCalculator();
                applet.init();
                
                frame.setContentPane(applet.getContentPane());
                
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                
                applet.start();
            }
        });
    }
    
    @Override
    public void init() {
        fxContainer = new JFXPanel();
        fxContainer.setPreferredSize(new Dimension(JFXPANEL_WIDTH_INT, JFXPANEL_HEIGHT_INT));
        add(fxContainer, BorderLayout.CENTER);
        // create JavaFX scene
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                createScene();
            }
        });
    }
    
    private void createScene() {
        JButton btn = new JButton();
        btn.setText("Say 'Hello World'");
        JRootPane root = new JRootPane();
        root.getContentPane().add(btn);
        fxContainer.setScene(new Scene(root));
    }
}
4

1 回答 1

5

此代码可用作小程序或桌面应用程序。这里:

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;

// <applet code=TutoringCalculator width=400 height=400></applet>
public class TutoringCalculator extends JApplet {

    // The size of an applet is set by the HTML!
    //private static final int JFXPANEL_WIDTH_INT = 300;
    //private static final int JFXPANEL_HEIGHT_INT = 250;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Tutoring Calculator");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JApplet applet = new TutoringCalculator();
                applet.init();

                frame.setContentPane(applet.getContentPane());

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                applet.start();
            }
        });
    }

    private JPanel swingContainer;

    @Override
    public void init() {
        swingContainer = new JPanel(new BorderLayout());
        add(swingContainer, BorderLayout.CENTER);
        createScene();
    }

    private void createScene() {
        JButton btn = new JButton();
        btn.setText("Say 'Hello World'");
        JRootPane root = new JRootPane();
        root.getContentPane().add(btn);
        swingContainer.add(root);
    }
}

我无法弄清楚您为什么要使用 aRootPane所以我保持原样。

更多提示

  • 规格。提到JFrame但没有JApplet。由于小程序的开发、调试和部署要困难得多,我建议您完全专注于让它在框架中工作。
  • 对于框架定位,你不能过去setLocationByPlatform(true)。有关演示,请参阅此答案
于 2013-05-15T04:46:18.870 回答