使用JavaFX显示JTable [英] Display JTable with JavaFX
问题描述
我想从网页上读取数字并在程序中使用它们。此程序显示网页,但如何显示网页下方的表格?如何在表格中填入网页上的日期和价格。
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){
//此方法在EDT线程上调用
JFrame frame =新的JFrame(Swing和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){
//此方法在JavaFX线程上调用
场景场景= createScene(url2);
fxPanel.setScene(scene);
}
private场景createScene(String url2){
场景场景=新场景(新Browser_1(url2),750,500,Color.web(#666970 ));
返回(场景);
}
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);
}
});
}
}
类Browser_1扩展Region {
最终的WebView浏览器=新的WebView();
final WebEngine webEngine = browser.getEngine();
public Browser_1(String url){
//应用样式
getStyleClass()。add(browser);
//加载网页
webEngine.load(url);
//将网页视图添加到场景
getChildren()。add(browser);
}
@SuppressWarnings(unused)
private Node createSpacer(){
Region spacer = new Region();
HBox.setHgrow(spacer,Priority.ALWAYS);
返回spacer;
}
@Override protected void layoutChildren(){
double w = getWidth();
double h = getHeight();
layoutInArea(浏览器,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大纲,
-
在后台添加一个合适的监听器
Worker
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
* /
公共类WebViewTable {
私有JTable表;
私有WebView webView;
private void initAndShowGUI(){
//此方法在EDT线程上调用
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){
//此方法在JavaFX线程上调用
场景场景= createScene();
fxPanel.setScene(scene);
}
private场景createScene(){
StackPane root = new StackPane();
场景场景=新场景(根);
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){
returnDocument URI;
}
@Override
public int getColumnCount(){
return 1;
}
@Override
public int getRowCount( ){
返回1;
}
@Override
public Object getValueAt(int row,int col){
返回webEngine.getDocument()。 getDocume ntURI();
}
});
});
}
});
webEngine.load(https://example.com);
root.getChildren()。add(webView);
返回场景;
}
public static void main(String [] 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屋!