Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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;
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
150 views
Welcome To Ask or Share your Answers For Others

1 Answer

In outline,

  • Add a suitable listener to the background Worker used by the WebEngine.

  • 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 the JTable when requested, possibly using the approach shown here.

  • Post a Swing event that invokes setModel() with the updated TableModel; the table will update itself accordingly.

Based on this example, the InvalidationListener below displays the result returned by getDocumentURI().

image

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);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...