使用 JavaFX 显示 JTable [英] Display JTable with JavaFX
问题描述
我想从网页中读取数字并在程序中使用它们.该程序显示网页,但如何显示网页下方的表格?以及如何使用网页中的日期和价格填充表格.
import java.awt.BorderLayout;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.JScrollPane;导入 javax.swing.JTable;导入 javax.swing.JTextArea;导入 javax.swing.SwingUtilities;导入 javax.swing.table.AbstractTableModel;导入 javax.swing.table.TableModel;导入 javafx.application.Platform;导入 javafx.embed.swing.JFXPanel;导入 javafx.scene.Scene;导入 javafx.scene.paint.Color;公开课 Step4 {私有无效initAndShowGUI(最终字符串网址){//该方法在 EDT 线程上调用JFrame frame = new JFrame("Swing and JavaFX");最终 JFXPanel fxPanel = 新 JFXPanel();JPanel mainPanel = new JPanel();mainPanel.setLayout(new BorderLayout());mainPanel.add(fxPanel, BorderLayout.NORTH);TableModel dataModel = new AbstractTableModel() {private static final long serialVersionUID = -147208558114868864L;公共 int getColumnCount() { 返回 10;}公共 int getRowCount() { 返回 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);框架.添加(主面板);框架.pack();frame.setSize(1000, 650);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);Platform.runLater(new Runnable() {@覆盖公共无效运行(){initFX(fxPanel, url);}});}私有无效initFX(JFXPanel fxPanel,字符串url2){//该方法在 JavaFX 线程上调用场景场景 = createScene(url2);fxPanel.setScene(场景);}私人场景 createScene(字符串 url2){Scene scene = new Scene(new Browser_1(url2),750,500, Color.web("#666970"));返回(场景);}公共静态无效主(字符串 [] args){最终字符串 url = "https://www.tsp.gov/investmentfunds/shareprice/sharePriceHistory.shtml";SwingUtilities.invokeLater(new Runnable() {@覆盖公共无效运行(){Step4 s = new Step4();s.initAndShowGUI(url);}});}}类 Browser_1 扩展区域 {最终的 WebView 浏览器 = new WebView();最终的 WebEngine webEngine = browser.getEngine();公共浏览器_1(字符串网址){//应用样式getStyleClass().add("浏览器");//加载网页webEngine.load(url);//将web视图添加到场景中getChildren().add(浏览器);}@SuppressWarnings("未使用")私有节点 createSpacer() {区域间隔=新区域();HBox.setHgrow(spacer, Priority.ALWAYS);回程垫片;}@Override protected void layoutChildren() {双 w = getWidth();双 h = getHeight();layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);}@Override protected double computePrefWidth(double height) {返回 750;}@Override 受保护的 double computePrefHeight(double width) {返回 500;}}
大纲,
为
import java.awt.BorderLayout;导入 java.awt.Dimension;导入 java.awt.EventQueue;导入 javax.swing.JFrame;导入 javafx.application.Platform;导入 javafx.beans.Observable;导入 javafx.concurrent.Worker;导入 javafx.embed.swing.JFXPanel;导入 javafx.scene.Scene;导入 javafx.scene.layout.StackPane;导入 javafx.scene.web.WebEngine;导入 javafx.scene.web.WebView;导入 javax.swing.JScrollPane;导入 javax.swing.JTable;导入 javax.swing.table.AbstractTableModel;/*** @see https://stackoverflow.com/a/32396344/230513* @see https://stackoverflow.com/a/31576647/230513*/公共类 WebViewTable {私有 JTable 表;私有 WebView webView;私人无效initAndShowGUI(){//该方法在 EDT 线程上调用JFrame frame = new JFrame("WebViewTable");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);最终 JFXPanel fxPanel = 新 JFXPanel(){@覆盖公共维度 getPreferredSize() {返回新维度(800, 400);}};frame.add(fxPanel, BorderLayout.CENTER);表 = 新 JTable(){@覆盖公共维度 getPreferredScrollableViewportSize() {返回新维度(800, 100);}};frame.add(new JScrollPane(table), BorderLayout.SOUTH);框架.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);Platform.runLater(() -> {initFX(fxPanel);});}私人无效initFX(JFXPanel fxPanel){//该方法在 JavaFX 线程上调用场景场景 = createScene();fxPanel.setScene(场景);}私人场景 createScene() {StackPane root = new StackPane();场景场景 = 新场景(根);webView = new WebView();WebEngine webEngine = webView.getEngine();工人工人 = webEngine.getLoadWorker();worker.stateProperty().addListener((Observable o) -> {如果(worker.getState() == Worker.State.SUCCEEDED){EventQueue.invokeLater(() -> {table.setModel(new AbstractTableModel() {@覆盖公共字符串 getColumnName(int col) {返回文档URI";}@覆盖公共 int getColumnCount() {返回 1;}@覆盖公共 int getRowCount() {返回 1;}@覆盖公共对象 getValueAt(int row, int col) {返回 webEngine.getDocument().getDocumentURI();}});});}});webEngine.load("https://example.com");root.getChildren().add(webView);返回场景;}公共静态无效主(字符串 [] args){EventQueue.invokeLater(new WebViewTable()::initAndShowGUI);}}
I'd like to read numbers from a web page and use them in a program. This program displays the web page, but how do I display the table below the web page? And how do I populate the table with the dates and prices from the web page.
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; } }
解决方案In outline,
Add a suitable listener to the background
Worker
used by theWebEngine
.In that suitable listener, traverse the Document Object Model of the web page for the results of interest, perhaps using the approach shown here.
Construct a
TableModel
that supplies the results to theJTable
when requested, possibly using the approach shown here.Post a Swing event that invokes
setModel()
with the updatedTableModel
; the table will update itself accordingly.
Based on this example, the
InvalidationListener
below displays the result returned bygetDocumentURI()
.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); } }
这篇关于使用 JavaFX 显示 JTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!