简体   繁体   English

将输出重定向到Java Swing中的表

[英]Redirecting output to table in Java Swing

Newbie here, I have a problem, redirecting my output to a Jtable. 新手在这里,我遇到了问题,将输出重定向到Jtable。 The data is coming from a different class that does the real work which is Scanner.java. 数据来自执行实际工作的另一个类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可以在控制台上打印我想要的内容,但是由于我添加了仍在学习的gui,所以我创建了一个新类MainFrame.java,并且我希望将搜索或扫描结果表格Scanner.java填充到我的JTable中,但是发现很难登录。

Scanner.java 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 . 最后,这是我的MainFrame.java文件。

![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. 我的另一个想法是将内容从Scanner.java类文件写入CSV并读取要填充表格的文件。 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". 基本上,您想从事件调度线程外部加载数据,以免阻塞UI并使它“挂起”。

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. 接下来,您需要某种方式来使Scanner发布其生成的信息,您可以通过多种方式来执行此操作,但是最简单的方法可能是使用生产者/消费者模式。

With the Scanner acting as the producer, we need some way to inform the consumer that new content is available. Scanner充当生产者,我们需要某种方式通知消费者新内容可用。 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. 注意,我通常更喜欢使用对象(例如POJO),但是我试图使其保持简单。

Next, we need to modify the Scannner to work with out Consumer ... 接下来,我们需要修改Scannner以与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. 现在,我们需要某种方法来启动Scanner并生成数据,首先创建基本的UI,然后启动SwingWorker ,将TableModel的引用传递给它,以便它可以添加新行。

    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... SwingWorker可以将所有内容结合在一起...

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 详细了解Worker Thread和SwingWorker以及如何使用表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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