亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Swing 中制作合適的 Table 以及使用合適的布局將所有元素放在各自的位置?

如何在 Swing 中制作合適的 Table 以及使用合適的布局將所有元素放在各自的位置?

青春有我 2023-06-04 17:11:53
我正在研究網絡爬蟲并分幾個階段實施。此階段獲取網站上提到的所有鏈接,并在 JTable 中顯示帶有標題的網頁的有效鏈接。但是,我希望在我在要解析的 TextField 中輸入 URL 之前該表已經存在(這是此分配的要求)。另外,有沒有辦法修復當前布局(Macintosh 窗口的第一張圖片)?當前 Swing 窗口?,以便我可以在指定位置正確顯示所有 JFrame 元素,如下圖所示:所有元素所在的所需擺動窗口我曾嘗試使用空布局來解決布局問題,這只會讓任務變成一場噩夢,而且表格會在我眼前消失。在我開始輸入鏈接之前,我找不到讓表格存在的方法。當我運行作業測試工具給出的測試時,它顯示“找不到合適的表元素”。發生這種情況是因為它甚至需要在將測試用例 URL 輸入文本字段進行解析之前檢測活動表。
查看完整描述

2 回答

?
浮云間

TA貢獻1829條經驗 獲得超4個贊

不要在JButton的ActionPerformed事件中創建JScrollPane和JTable。但是,如果您愿意,可以從該事件重新啟用 JTable,并將鏈接應用到 JTable 的模型。


如果可以,請在單獨的類中創建您的表單。這清理了很多東西,因為它使表單代碼雜亂無章,遠離手頭的主要任務……頁面抓取鏈接。表單類可能如下所示:


package webcrawler;


public class Form extends javax.swing.JFrame {


private static final long serialVersionUID = 101101L;


// Member Variables for Form Components 

public javax.swing.JTextField urlText;

public javax.swing.JButton extract;

public javax.swing.JLabel title;

public javax.swing.JTable table;


private javax.swing.JLabel jLabel1;

private javax.swing.JPanel jPanel1;

private javax.swing.JPanel jPanel2;

private javax.swing.JScrollPane scrollPane;

private javax.swing.JLabel titleLabel;


public Form() {

    initializeFormComponents();

    setLookAndFeel();

    openForm();

}


private void setLookAndFeel() {

    /* Set the Nimbus look and feel if you have it 

       or even like it. Use whatever you like   */

    try {

        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {

            if ("Nimbus".equals(info.getName())) {

                javax.swing.UIManager.setLookAndFeel(info.getClassName());

                break;

            }

        }

    }

    catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {

        System.out.println(ex.getMessage());

    }

}


private void openForm() {

    /* Create and display the form */

    java.awt.EventQueue.invokeLater(new Runnable() {

        @Override

        public void run() {

            setVisible(true);

            setLocationRelativeTo(null);

        }

    });

}


private void initializeFormComponents() {

    jPanel1 = new javax.swing.JPanel();

    jLabel1 = new javax.swing.JLabel();

    urlText = new javax.swing.JTextField();

    extract = new javax.swing.JButton();

    jPanel2 = new javax.swing.JPanel();

    scrollPane = new javax.swing.JScrollPane();

    table = new javax.swing.JTable();

    titleLabel = new javax.swing.JLabel();

    title = new javax.swing.JLabel();


    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    setTitle("Web Crawler");

    setAlwaysOnTop(true);


    jLabel1.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N

    jLabel1.setText("URL:");

    urlText.setName("UrlTextField"); // NOI18N

    extract.setText("Parse");

    extract.setName("RunButton"); // NOI18N


    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);

    jPanel1.setLayout(jPanel1Layout);

    jPanel1Layout.setHorizontalGroup(

            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                    .addGroup(jPanel1Layout.createSequentialGroup()

                            .addContainerGap()

                            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)

                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

                            .addComponent(urlText, javax.swing.GroupLayout.PREFERRED_SIZE, 667, javax.swing.GroupLayout.PREFERRED_SIZE)

                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

                            .addComponent(extract, javax.swing.GroupLayout.DEFAULT_SIZE, 84, Short.MAX_VALUE)

                            .addContainerGap())

    );

    jPanel1Layout.setVerticalGroup(

            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                    .addGroup(jPanel1Layout.createSequentialGroup()

                            .addContainerGap()

                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)

                                    .addComponent(jLabel1)

                                    .addComponent(urlText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

                                    .addComponent(extract))

                            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))

    );


    table.setModel(new javax.swing.table.DefaultTableModel(

            new Object[][]{

                {null, null},

                {null, null},

                {null, null},

                {null, null}

            },

            new String[]{

                "URL", "TITLE"

            }

    ) {

        private static final long serialVersionUID = 101110L;

        Class[] types = new Class[]{

            java.lang.String.class, java.lang.String.class

        };

        boolean[] canEdit = new boolean[]{

            false, false

        };


        @Override

        public Class getColumnClass(int columnIndex) {

            return types[columnIndex];

        }


        @Override

        public boolean isCellEditable(int rowIndex, int columnIndex) {

            return canEdit[columnIndex];

        }

    });

    table.setName("TitlesTable");

    table.setEnabled(false);

    table.setGridColor(new java.awt.Color(198,195,195));

    table.setInheritsPopupMenu(true);

    table.setRowHeight(20);

    table.setShowHorizontalLines(true);

    table.setShowVerticalLines(true);

    scrollPane.setViewportView(table);


    titleLabel.setFont(new java.awt.Font("sansserif", 1, 12));

    titleLabel.setText("Title:");


    title.setFont(new java.awt.Font("sansserif", 1, 12));

    title.setText("None");

    title.setName("TitleLabel");


    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);

    jPanel2.setLayout(jPanel2Layout);

    jPanel2Layout.setHorizontalGroup(

            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                    .addGroup(jPanel2Layout.createSequentialGroup()

                            .addContainerGap()

                            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                                    .addComponent(scrollPane)

                                    .addGroup(jPanel2Layout.createSequentialGroup()

                                            .addComponent(titleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)

                                            .addGap(18, 18, 18)

                                            .addComponent(title, javax.swing.GroupLayout.PREFERRED_SIZE, 348, javax.swing.GroupLayout.PREFERRED_SIZE)

                                            .addGap(0, 0, Short.MAX_VALUE)))

                            .addContainerGap())

    );

    jPanel2Layout.setVerticalGroup(

            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()

                            .addContainerGap()

                            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)

                                    .addComponent(titleLabel)

                                    .addComponent(title))

                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)

                            .addComponent(scrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 478, javax.swing.GroupLayout.PREFERRED_SIZE)

                            .addContainerGap())

    );


    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());

    getContentPane().setLayout(layout);

    layout.setHorizontalGroup(

            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

    );

    layout.setVerticalGroup(

            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

                    .addGroup(layout.createSequentialGroup()

                            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

                            .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))

    );

        pack();

    }

}

然后您的 WebCrawler 類可能如下所示:


package webcrawler;


import javax.swing.*;

import javax.swing.table.DefaultTableModel;

import javax.swing.table.TableModel;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.URL;

import java.nio.charset.StandardCharsets;

import java.util.Iterator;

import java.util.Map;

import java.util.SortedMap;

import java.util.TreeMap;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import javax.swing.table.JTableHeader;

import javax.swing.table.TableCellRenderer;



public class WebCrawler {


private static final long serialVersionUID = 101011L;

private Form form;

String LINE_SEPARATOR = System.getProperty("line.separator");


public static void main(String[] args) {

    // To eliminate the need for statics. I Don't want it right now. 

    new WebCrawler().startApp(args);

}


private void startApp(String[] args) {

    form = new Form();

    form.extract.addActionListener(new ActionListener() {

        @Override

        public void actionPerformed(ActionEvent e) {

            try {

                clearJTable();  // Clear the JTable

                String url = form.urlText.getText();

                /* Get url from JTextField */

                url = url.replaceAll("^\"+ \"+$", "");


                final InputStream inputStream = new URL(url).openStream();

                final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

                final StringBuilder stringBuilder = new StringBuilder();


                String nextLine;

                while ((nextLine = reader.readLine()) != null) {

                    stringBuilder.append(nextLine);

                    stringBuilder.append(LINE_SEPARATOR);

                }


                final String siteText = stringBuilder.toString();


                Pattern pattern = Pattern.compile("<title>(.+?)</title>", Pattern.CASE_INSENSITIVE);

                Matcher matcher = pattern.matcher(siteText);


                String titleString = matcher.find() ? matcher.group(1) : "null";

                form.title.setText(titleString);


                SortedMap<String, String> links = new TreeMap<>();


                Pattern pTag = Pattern.compile("(?i)<a([^>]+)>(.+?)</a>", Pattern.CASE_INSENSITIVE);

                Pattern pLink = Pattern.compile("\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))", Pattern.CASE_INSENSITIVE);


                Matcher mTag = pTag.matcher(siteText);


                try {

                    while (mTag.find()) {


                        String href = mTag.group(1);     // get the values of href

                        String linkElem = mTag.group(2); // get the text of link Html Element


                        Matcher mLink = pLink.matcher(href);


                        while (mLink.find()) {

                            String link = mLink.group(1);

                            link = link.substring(1, link.length() - 1);

                            pattern = Pattern.compile("http", Pattern.CASE_INSENSITIVE);

                            matcher = pattern.matcher(link);

                            if (!matcher.find()) {

                                link = String.join("", url, link);

                            }

                            try {

                                //URL urlValidator = new URL(link);

                                //if (urlValidator.getContent().equals("text/html")) {

                                links.put(link, linkElem);

                                //}

                            }

                            catch (Exception ex) {

                                System.out.println(ex);

                                //System.out.println("Exception encountered at " + link);

                            }

                        }

                    }

                    form.table.setEnabled(true);    // Enable JTable

                    form.table.setModel(toTableModel(links));

                }

                catch (Exception ex) {

                    System.out.println(ex);

                }

            }

            catch (Exception ex) {

                System.out.println(ex);

            }

            // Is there anything in the table?

            if (form.table.getModel().getRowCount() == 0) {

                // NOPE...So Disable JTable.

                form.table.setEnabled(true);

            }

        }

    });

    form.urlText.requestFocus();

}


private void clearJTable() {

    DefaultTableModel tableModel = (DefaultTableModel) form.table.getModel();

    while (tableModel.getRowCount() > 0) {

        for (int i = 0; i < tableModel.getRowCount(); i++) {

            tableModel.removeRow(i);

        }

    }

    // Reset 4 blank rows in the table for looks :) 

    form.table.setModel(new DefaultTableModel(

            new Object[][]{{null, null}, {null, null}, {null, null},{null, null}},

            new String[]{"<html><font color=blue><b>U R L</b></font></html>", 

                         "<html><font color=red><b>T I T L E</b></font></html>"}));

    // Yes...you can use basic HTML in a JTable Header.

}


public TableModel toTableModel(Map<?, ?> map) {

    DefaultTableModel model = new DefaultTableModel(

            new Object[]{"URL", "TITLE"}, 0

    );

    for (Iterator it = map.entrySet().iterator(); it.hasNext();) {

        Map.Entry entry = (Map.Entry) it.next();

        model.addRow(new Object[]{entry.getKey(), entry.getValue()});

    }

    return model;

}


}



查看完整回答
反對 回復 2023-06-04
?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

我希望在輸入 URL 之前表格已經存在


然后,您需要在創建所有其他組件并將其添加到框架的同時創建一個空表并將其添加到框架。


您需要為 JTable 創建一個實例變量才能修改其模型。


將表格添加到框架的代碼類似于:


add(title, BorderLayout.LINE_START);

DefaultTableModel model = new DefaultTableModel (new Object[] { "URL", "Title" }, 0);

table = new JTable( model );

add(new JScrollPane(table), BorderLayout.CENTER);

所以現在當您啟動應用程序時,您將看到一個只有列的空表。


您的方法中的代碼toTableModel(...)現在變成如下所示:


//DefaultTableModel model = new DefaultTableModel (new Object[] { "URL", "Title" }, 0);

DefaultTableModel model = (DefaultTableModel)table.getModel();

model.setRowCount(0);

這只是刪除模型中的所有行,因此您的循環代碼可以添加每一行新數據。


當然,您還可以刪除當前創建 JTable 和 JScrollPane 的 ActionListener 中的代碼,因為不再需要它。


另外,有沒有辦法修復當前布局


您的嵌套面板具有不同的布局管理器,以達到您想要的效果。


例如,您希望表格能夠根據表格中的數據增長/縮小,因此應該將其添加到CENTER您的BorderLayout.


但是,頂部到兩行是固定的,它們應該添加到子面板中。然后這個面板將被添加到PAGE_START你的BorderLayout. Maybe a verticalBoxLayout` 中。


然后每一行都是另一個子面板。第一行可以是帶有水平的面板BoxLayout,第二行可以是帶有FlowLayout.


查看完整回答
反對 回復 2023-06-04
  • 2 回答
  • 0 關注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號