java程式通過swing呼叫javaFx更新 資料

噴氣輪胎發表於2018-03-26

執行優先順序關係,java無法直接呼叫javaFx,試過通過反射等方法都不好用,最後使用SWing中轉實現和javaFx互操。

首先建立SWing呼叫javaFX類

import javafx.application.Platform;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker.State;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;

public class SwingSample extends JFrame {

    private final JFXPanel jfxPanel = new JFXPanel();
    private WebEngine engine;
    private Label lab = new Label("test");

    private final JPanel panel = new JPanel(new BorderLayout());
    private final JLabel lblStatus = new JLabel();

    public SwingSample() {
        super();
        initComponents();
    }

    private void initComponents() {
        createScene();
        JPanel statusBar = new JPanel(new BorderLayout(5, 0));
        statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
        statusBar.add(lblStatus, BorderLayout.CENTER);

        panel.add(jfxPanel, BorderLayout.CENTER);
        panel.add(statusBar, BorderLayout.SOUTH);
        getContentPane().add(panel);
        setPreferredSize(new Dimension(1024, 600));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

    private void createScene() {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {

                WebView view = new WebView();
                engine = view.getEngine();

                engine.getLoadWorker().stateProperty()
                        .addListener((ObservableValue<? extends State> ov, State oldState, State newState) -> {
                            if (newState == State.SUCCEEDED) {
                                JSObject win = (JSObject) engine.executeScript("window");
                                win.setMember("javaApi", new JavaApp()); // 設定介面到JavaScript中
                            }
                        });

                lab.setFont(new Font("Arial", 30));
                lab.setTextFill(Color.web("#0076a3"));
                lab.setTextAlignment(TextAlignment.JUSTIFY);
                HBox h = new HBox();
                h.getChildren().addAll(view, lab);

                jfxPanel.setScene(new Scene(h));
            }
        });
    }

    public void change(int step) {
        System.out.println("c = " + step);
        Platform.runLater(() -> lab.setText("i=" + step));
    }

    public void runJs() {
        Platform.runLater(() -> engine.executeScript("sayGoodbye('running from java')"));
    }

    public void loadURL(final String url) {
        System.out.println(url);
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                String tmp = toURL(url);

                if (tmp == null) {
                    tmp = toURL("http://" + url);
                }
                engine.load(tmp);
            }
        });
    }

    private static String toURL(String str) {
        try {
            return new URL(str).toExternalForm();
        } catch (MalformedURLException exception) {
            return null;
        }
    }

    public class JavaApp {

        public void exit() {
            Platform.exit();
        }

        public String getData(String data) {
            System.out.println(data);
            return "hi " + data ;
        }
        
        public double setDate(double data) {
            System.out.println(data);
            return data * 10;
        }

        public String getJson() {
            return "{\"msg\":\"查詢 成功!\",\"code\":0,\"data\":{\"isOK\":true,\"code\":\"100\"}}";
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                SwingSample browser = new SwingSample();
                browser.setVisible(true);
                browser.loadURL(getClass().getResource("help.html").toExternalForm());
            }
        });
    }

}

建立html頁面

<html lang="en">
    <head>
        <script type="text/javascript">
        
            function setDate(data)  {
                document.getElementById("my_message").innerHTML = data;
            }
            
            function getData(data)  {
                var  message  = javaApi.getData(data);
                document.getElementById("my_message").innerHTML = message;
            }
            
            function getJson()  {
                var  json  = javaApi.getJson();
                document.getElementById("my_json").innerHTML = json;
            }
            function getJsonObj()  {
                var  json  = JSON.parse(javaApi.getJson()); 
                document.getElementById("my_json2").innerHTML = json.code;
            }
            
        </script>
    </head>
    <body>
        <h1>javafx import java </h1>
     <p><a href="about:blank" οnclick="javaApi.exit()">Exit the Application</a></p>
     <button οnclick="getJson()">getJson</button>
     <button οnclick="getJsonObj()">getJsonObj</button>
     <button οnclick="javaApi.setDate(20)">setDateJava</button>
     <button οnclick="javaApi.getData('js')">getDataJava</button>
     <button οnclick="getData('js')">getDataJs</button>
     <div  id="my_message"></div>
     <div  id="my_list"></div>
     <div  id="my_json"></div>
     <div  id="my_json2"></div>
    </body>
</html>



最後編寫測試java程式

import java.util.concurrent.TimeUnit;
import javax.swing.SwingUtilities;

public class Test {

	public static int tm = 100;
	static SwingSample browser = new SwingSample();

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

	public static void runSwing() {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				browser.setVisible(true);
				browser.loadURL(SwingSample.class.getResource("help.html").toExternalForm());
			}
		});
	}

	public static void task() {
		new Thread(() -> {
			int i = 0;
			while (i++ < 10) {
				try {
					TimeUnit.SECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(i);
				work(i);
			}
			browser.runJs();
		}).start();
	}

	public static void work(int i) {
		browser.change(i);
	}

}

java程式呼叫javaFx方法更新 javaFX,可以把java程式計算的結果實時顯示在javaFx上。

使用SWing中轉可以方便的隨時呼叫javaFX,畫圖,表格等 視覺化功能。












相關文章