简体   繁体   中英

Redirecting output to table in Java Swing

Newbie here, I have a problem, redirecting my output to a Jtable. The data is coming from a different class that does the real work which is Scanner.java.

With this said, Scanner.java could print what i want on console but since I added gui which am still learning I have created a new class MainFrame.java and I want search or scan result form Scanner.java to be populated in my JTable but am finding it hard to get the login.

Scanner.java

public void getCompanyProfile(){
     Document sourceCode;

            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        List<String> allLinks = results();
                        Document sourceCode;
                        int counter = 1;
                        for (String link : allLinks){
                            System.out.println("Link #:" + counter + " " + link);
                            sourceCode = PageVisitor.getHtmlSource(link);
                            Elements profile = sourceCode.select("div.company a.cd");
                            for (Element links : profile) {
                                String linkHref = links.attr("href");
                                System.out.println(linkHref);
                                setUserData(linkHref);
                            }
                            counter++;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });

        }

        private void setUserData(String url) throws IOException{
            Extractor data = new Extractor();
            // Scan each page alibaba initial result
            data.setProfile(url);
            this.companyName = data.getName();
            this.country = data.getCountry();
            HashSet<String> webites = data.getSellerUrls();

            this.webAndEmail = new HashMap<String, HashSet<String>>();
            HashSet<String> emails;

            for (String webs: webites){
                emails = data.emailExtractor(webs);
                webAndEmail.put(webs, emails);
                for (String anEmail : emails){
//This is the part i want to be displayed in my JTable Component.
                    System.out.println("Company=" +companyName + ", country=" + country + ", web=" 
                + webs + ", email=" + anEmail);
                }
            }

        }

        public String getProductName(){
            return this.product;
        }
        public String getSource(){
            return this.source;
        }
        public String getCompanyName(){
            return this.companyName;
        }
        public String getCountry(){
            return this.country;
        }
        public Map<String, HashSet<String>> getWebandEmail(){
            return this.webAndEmail;
        }

Finally, this is my MainFrame.java file below .

![JButton btnStart = new JButton("Start");
        btnStart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {


            }
        });
        btnStart.setBounds(197, 166, 75, 29);
        frame.getContentPane().add(btnStart);



    //more statements like the above to establish all col. titles       
         String\[\] columnNames = {"Company Name", "Email", "Website", "Country", "Product", "Source"};
         //Sample data to be printed
            Object\[\]\[\] data =
            {
                {"Code Java Ltd", "bingo@codejava.net", "http://www.codejava.com", "Universe", "Polythecnic", "Ebay - B2B"},

            };

            DefaultTableModel model = new DefaultTableModel(data, columnNames) {

                @Override
                public boolean isCellEditable(int row, int column) {
                    //all cells false
                    return false;
                }
            };



        resultTable = new JTable(model);
        //resultTable.setBounds(37, 259, 553, 143);
        resultTable.getColumnModel().getColumn(0).setPreferredWidth(150);
        resultTable.getColumnModel().getColumn(1).setPreferredWidth(150);
        resultTable.getColumnModel().getColumn(2).setPreferredWidth(150);
        resultTable.getColumnModel().getColumn(3).setPreferredWidth(150);
        resultTable.getColumnModel().getColumn(4).setPreferredWidth(100);
        resultTable.getColumnModel().getColumn(5).setPreferredWidth(100);

        resultTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 

        JScrollPane scrollPane = new JScrollPane( resultTable );
        scrollPane.setBounds(37, 259, 806, 143);
        frame.getContentPane().add( scrollPane );
        //frame.add(resultTable);

        JButton button = new JButton("Stop");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            }
        });
        button.setBounds(289, 166, 75, 29);
        frame.getContentPane().add(button);][1]

This is what am trying to attain. My other idea is to write the content to CSV from Scanner.java class file and read the file lated to populate the table. But like I said, am a beginner still don't think it would be that easy. So I kindly need someone to point me in the right direction.

Basically, you want to load your data from outside the Event Dispatching Thread, so as not to block the UI and make it "hang".

Next, you need some way for the Scanner to publish information it has generated, there are a number of ways you might do this, but the simplest might to use something like a Produce/Consumer Pattern.

With the Scanner acting as the producer, we need some way to inform the consumer that new content is available. Start with a simple interface...

public interface Consumer {

    public void publish(String company, String country, String webLink, String email);

}

Note, I normally prefer to use objects (like a POJO), but I'm trying to keep it simple.

Next, we need to modify the Scannner to work with out Consumer ...

public class Scanner {

    public void getCompanyProfile(Consumer consumer) {
        Document sourceCode;
        List<String> allLinks = results();
        Document sourceCode;
        int counter = 1;
        for (String link : allLinks) {
            System.out.println("Link #:" + counter + " " + link);
            sourceCode = PageVisitor.getHtmlSource(link);
            Elements profile = sourceCode.select("div.company a.cd");
            for (Element links : profile) {
                String linkHref = links.attr("href");
                System.out.println(linkHref);
                setUserData(linkHref);
            }
            counter++;
        }
    }

    private void setUserData(String url, Consumer consumer) throws IOException {
        Extractor data = new Extractor();
        // Scan each page alibaba initial result
        data.setProfile(url);
        this.companyName = data.getName();
        this.country = data.getCountry();
        HashSet<String> webites = data.getSellerUrls();

        this.webAndEmail = new HashMap<String, HashSet<String>>();
        HashSet<String> emails;

        for (String webs : webites) {
            emails = data.emailExtractor(webs);
            webAndEmail.put(webs, emails);
            for (String anEmail : emails) {
                consumer.publish(companyName, country, webs, anEmail);
            }
        }

    }

    public String getProductName() {
        return this.product;
    }

    public String getSource() {
        return this.source;
    }

    public String getCompanyName() {
        return this.companyName;
    }

    public String getCountry() {
        return this.country;
    }

    public Map<String, HashSet<String>> getWebandEmail() {
        return this.webAndEmail;
    }
}

Now, we need some way to get the Scanner started and producing data, first we create the basic UI and then we start a SwingWorker , passing a reference of the TableModel to it, so it can add the new rows.

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }

            DefaultTableModel model = new DefaultTableModel(new String[]{"Company Name", "Email", "Website", "Country", "Product", "Source"}, 0);
            JTable table = new JTable(model);
            // Initialise remainder of the UI...

            ScannerWorker worker = new ScannerWorker(model);
            worker.execute();
        }
    });

And the SwingWorker to hold it all together...

public class ScannerWorker extends SwingWorker<Object, String[]> implements  Consumer {

    private DefaultTableModel tableModel;

    public ScannerWorker(DefaultTableModel tableModel) {
        this.tableModel = tableModel;
    }

    @Override
    protected Object doInBackground() throws Exception {
        Scanner scanner = new Scanner();
        scanner.getCompanyProfile(this);
        return null;
    }

    @Override
    public void publish(String company, String country, String webLink, String email) {
        publish(new String[]{company, email, webLink, country, "", ""});
    }

    @Override
    protected void process(List<String[]> chunks) {
        for (String[] rowData : chunks) {
            tableModel.addRow(rowData);
        }
    }

}

Take a closer look at Worker Threads and SwingWorker and How to Use Tables for more details

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM