使用JavaFX显示JTable

我想从网页上读取数字并在程序中使用它们。 此程序显示网页,但如何显示网页下方的表格? 如何使用网页中的日期和价格填充表格。

import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableModel; import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.paint.Color; public class Step4 { private void initAndShowGUI(final String url) { // This method is invoked on the EDT thread JFrame frame = new JFrame("Swing and JavaFX"); final JFXPanel fxPanel = new JFXPanel(); JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); mainPanel.add(fxPanel, BorderLayout.NORTH); TableModel dataModel = new AbstractTableModel() { private static final long serialVersionUID = -147208558114868864L; public int getColumnCount() { return 10; } public int getRowCount() { return 10;} public Object getValueAt(int row, int col) { return new Integer(row*col); } }; JTable table = new JTable(dataModel); JScrollPane tableContainer = new JScrollPane(table); JPanel display = new JPanel(); display.setLayout(new BorderLayout()); display.add(tableContainer, BorderLayout.CENTER); mainPanel.add(display, BorderLayout.SOUTH); frame.add(mainPanel); frame.pack(); frame.setSize(1000, 650); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Platform.runLater(new Runnable() { @Override public void run() { initFX(fxPanel, url); } }); } private void initFX(JFXPanel fxPanel, String url2) { // This method is invoked on the JavaFX thread Scene scene = createScene(url2); fxPanel.setScene(scene); } private Scene createScene(String url2) { Scene scene = new Scene(new Browser_1(url2),750,500, Color.web("#666970")); return (scene); } public static void main(String[] args) { final String url = "https://www.tsp.gov/investmentfunds/shareprice/sharePriceHistory.shtml"; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Step4 s = new Step4(); s.initAndShowGUI(url); } }); } } class Browser_1 extends Region { final WebView browser = new WebView(); final WebEngine webEngine = browser.getEngine(); public Browser_1(String url) { //apply the styles getStyleClass().add("browser"); // load the web page webEngine.load(url); //add the web view to the scene getChildren().add(browser); } @SuppressWarnings("unused") private Node createSpacer() { Region spacer = new Region(); HBox.setHgrow(spacer, Priority.ALWAYS); return spacer; } @Override protected void layoutChildren() { double w = getWidth(); double h = getHeight(); layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER); } @Override protected double computePrefWidth(double height) { return 750; } @Override protected double computePrefHeight(double width) { return 500; } } 

概括地说,

  • 将合适的侦听器添加到WebEngine使用的后台Worker

  • 在该合适的监听器中,可以使用此处所示的方法遍历网页的文档对象模型以获得感兴趣的结果。

  • 构造一个TableModel ,在请求时将结果提供给JTable ,可能使用此处显示的方法。

  • 发布一个Swing事件,该事件使用更新的TableModel调用setModel() ; 该表将相应地更新自己。

基于此示例 ,下面的InvalidationListener显示getDocumentURI()返回的结果。

图片

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import javax.swing.JFrame; import javafx.application.Platform; import javafx.beans.Observable; import javafx.concurrent.Worker; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; /** * @see https://stackoverflow.com/a/32396344/230513 * @see https://stackoverflow.com/a/31576647/230513 */ public class WebViewTable { private JTable table; private WebView webView; private void initAndShowGUI() { // This method is invoked on the EDT thread JFrame frame = new JFrame("WebViewTable"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final JFXPanel fxPanel = new JFXPanel(){ @Override public Dimension getPreferredSize() { return new Dimension(800, 400); } }; frame.add(fxPanel, BorderLayout.CENTER); table = new JTable(){ @Override public Dimension getPreferredScrollableViewportSize() { return new Dimension(800, 100); } }; frame.add(new JScrollPane(table), BorderLayout.SOUTH); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); Platform.runLater(() -> { initFX(fxPanel); }); } private void initFX(JFXPanel fxPanel) { // This method is invoked on the JavaFX thread Scene scene = createScene(); fxPanel.setScene(scene); } private Scene createScene() { StackPane root = new StackPane(); Scene scene = new Scene(root); webView = new WebView(); WebEngine webEngine = webView.getEngine(); Worker worker = webEngine.getLoadWorker(); worker.stateProperty().addListener((Observable o) -> { if (worker.getState() == Worker.State.SUCCEEDED) { EventQueue.invokeLater(() -> { table.setModel(new AbstractTableModel() { @Override public String getColumnName(int col) { return "Document URI"; } @Override public int getColumnCount() { return 1; } @Override public int getRowCount() { return 1; } @Override public Object getValueAt(int row, int col) { return webEngine.getDocument().getDocumentURI(); } }); }); } }); webEngine.load("https://example.com"); root.getChildren().add(webView); return scene; } public static void main(String[] args) { EventQueue.invokeLater(new WebViewTable()::initAndShowGUI); } }