首页 > 解决方案 > 搜索按钮从其他 JFrame 中的表中选择数据

问题描述

一个JFrame1 有一个JTextField和一个Jbutton(按钮搜索)从表中选择提供者的名称(该表存在于另一个 JFrame 中),我还有其他JTextField的要填写JFrame1。

我想用JTextField从表中选择的值填充第一个。

代码1:搜索按钮:

public class OrderForm extends javax.swing.JFrame {

/**
 * Creates new form OrderForm
 */
public OrderForm() {
    initComponents();
    this.setLocationRelativeTo(null);
    providerName.setEditable(false);
}

private void searchActionPerformed(java.awt.event.ActionEvent evt) {                                       
    ProvidersForm pF = new ProvidersForm( this );
    pF.setVisible(true);
    setVisible(false);
}  

在此处输入图像描述

问题是:当我从表中选择一行时,我不需要创建一个新JFrame的,我需要返回到上一个具有 sercha 按钮的 jframe 并设置其中选择的值JTextField。因为如果我这样做,在其余字段中输入的数据将消失

代码2:第二个JFrame(有一个提供者表):

public class ProvidersForm extends javax.swing.JFrame {

/**
 * Creates new form ProvidersForm
 */
private static JFrame mainForm;
public ProvidersForm(JFrame form) {
    initComponents();
    this.setLocationRelativeTo(null);
    mainForm = form;
}
OrderForm ofRowData = new OrderForm();

   private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {                                     
   int index = jTable1.getSelectedRow();
   TableModel model = jTable1.getModel();
   String nom = model.getValueAt(index, 0).toString();
   String pré = model.getValueAt(index, 1).toString();

   ofRowData.setVisible(true);
   ofRowData.pack();
   ofRowData.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

   ofRowData.providerName.setText(nom + pré);
}                                    

在此处输入图像描述 在此处 输入图像描述

注意:我将 OrderForm JFrame 参数传递给 ProviderForm

mainForm = 订单

标签: javaswingjframejtable

解决方案


如果您正在执行搜索,您可以利用TableRowSorter#setRowFilter()方法直接在表格中而不是在某个文本字段组件中显示该搜索(无论它是什么)。换句话说....让表格本身显示符合您的搜索条件的记录。您的搜索条件也可以接受正则表达式。毕竟,有时可能会有多个记录满足搜索条件。

在此示例中,您的 JTable 需要作为类成员变量声明为公共静态(而非私有)。

通过过滤查看表记录:

/**
 * Make sure the supplied JTable's DefaultTableModel already contains data
 * before calling this method.<br><br>
 * <p>
 * The JTable always retains the data it is currently filled with within its
 * Table Model. <b>Knowing this we can theoretically fill the Table with all
 * database table records then use the Filter to display only the specific
 * table records we want.</b> This way we don't have to pole the database
 * for different records all the time and records acquisition is greatly
 * increased.<br><br>
 * <p>
 * This method will pass the supplied Filter text across the supplied JTable
 * and will force that JTable to only display records (contained within that
 * JTable at the time) which contains that specific text. It reacts very
 * much like a search engine for the JTable.<br><br>
 * <p>
 * If you want to display all records again which were originally contained
 * within the supplied JTable then just pass a Null String ("") within the
 * filterText parameter of this method.<br><br>
 *
 * @param table          (JTable) The JTable to run filter on.<br>
 *
 * @param searchCriteria (String) The text to filter JTable with. Passing a 
 * Null String ("") will force the table to display all records. Regular 
 * Expressions (RegEx) can also be supplied within the criteria string. If 
 * the wildcard characters <b>?</b> or <b>*</b> are supplied within the filter 
 * criteria String without any RegEx meta characters then the functional purpose 
 * of these two wildcard characters are converted to RegEx when encountered. If 
 * actual Regular Expressions are going to be used to make up the search criteria 
 * string then be sure to set the <b>endorseWildcards</b> optional parameter to 
 * boolean false since the <b>?</b> and <b>*</b> wildcard characters have 
 * different meaning within a Regular Expression and must be handled differently.<br>
 *
 * @param options (optional - Integer/Boolean):<pre>
 * 
 *     byColumnNumber - (Optional - Integer - Default is -1) By default
 *                       this method filters across all table columns but
 *                       you can be column specific if you pass a column
 *                       number to this optional parameter. This parameter
 *                       accepts only a <b>Literal Column Number</b> which
 *                       means that although the first column within a
 *                       JTable is considered column 0, to this method it is
 *                       considered as column 1.
 * 
 *    endorseWildcards - (boolean) Default is true (allow wildcards). If true 
 *                       then when a wildcard character is encountered within
 *                       a search criteria string it is automatically converted
 *                       to its RegEx equivalent. The two wildcard characters 
 *                       are almost always more than enough to carry out any 
 *                       search required and is usually much easier to use than 
 *                       some complex regular expressions. If endorseWildcards
 *                       is true then upper or lower letter case is ignored as
 *                       well.
 * 
 *                       If you provide a true of false to this parameter then
 *                       you must provide a value (or null) to the option 
 *                       <b>byColumnNumber</b> parameter.</pre>
 */
public static void FilterTable(JTable table, String searchCriteria, Object... options) {
    int column = -1;
    boolean endorseWildcards = true;
    if (options.length > 0) {
        if (options[0] != null) {
            column = (int)options[0] - 1;
        }
        if (options.length >= 2) {
            if (options[1] != null) {
                endorseWildcards = (boolean)options[1];
            }
        }
    }

    String criteria = searchCriteria;
    if (endorseWildcards) {
        criteria = "(?i)" + searchCriteria.replace("?", ".?").replace("*", ".*?");
    }

    try {
        TableRowSorter<TableModel> sorter = new TableRowSorter<>(((DefaultTableModel) table.getModel()));
        sorter.setRowFilter(column < 0 ? RowFilter.regexFilter(criteria) : 
                            RowFilter.regexFilter(criteria, column));
        table.setRowSorter(sorter);
    }
    catch (Exception ex) {
        ex.printStackTrace();
    }
}

这是一个小示例的链接,说明您可能希望如何使用此方法。这是创建它的代码的链接。

但是从外观上看,这并不是您要寻找的东西,事实上,很难准确地理解您要做什么。因此,我将只提供一些真正的通用 JTable 搜索方法,您可以对其进行修改以满足您的特定需求。

方法#1:

/**
 * Searches all the <b>selected</b> record rows of the supplied JTable within the supplied 
 * literal column number for the supplied Search criteria and if found will then returns 
 * the data contained within the supplied row column of the same record. So, if we have 
 * records with the following scheme:<pre>
 * 
 *    ID    Name            Age    Address            Phone
 *    ==============================================================
 *    1     Jack Black      22     3232 Main St.      (544) 666-3232 
 *    2     Tracey Johnson  43     1217 Gladwin Rd.   (544) 666-8888
 *    3     John Doe        32     2212 Main Street   (544) 322-5555
 *    4     Flash Gordon    28     55432 1st Ave      (544) 656-9685</pre><br>
 * 
 * and we want all the names of people that live on "Main Street" we would use this method 
 * like this:<pre>
 * 
 *    {@code List<String> results = searchSelectedTableRows(MyClass.MyTable, 4, "* Main St*", 2);
 *      for (String str : results) {
 *          System.out.println(str);
 *      }}</pre><br>
 * 
 * This will be displayed within the Console Window:<pre>
 * 
 *      Jack Black
 *      John Doe</pre><br>
 * 
 * @param table (JTable) The JTable object to search.<br>
 * 
 * @param searchInColumn (Integer - Literal) The literal table column number 
 * to carry out the search in. This method will check this column in each table 
 * record for all possible matches to the supplied search criteria string.
 * 
 * @param searchCriteria (String) The search criteria string. The specific data 
 * to search for. You can also utilize the <b>?</b> and <b>*</b> wildcard 
 * characters within your search criteria string to make your search as wide 
 * as you like. You can even utilize a Regular Expression for your search 
 * criteria string providing you supply boolean <b>false</b> to the optional 
 * <b>endorseWildcards</b> parameter.<br><br>
 * 
 * @param returnDataInColumnNumber (Integer - Literal) The literal column 
 * number of the data you want to retain (have stored in the returned List) 
 * from the record(s) the meet the search criteria.<br>
 * 
 * @param endorseWildcards (Boolean) Default is <b>true</b> (allow wildcards). If true 
 * then when a wildcard character is encountered within a search criteria string 
 * it is automatically converted to its RegEx equivalent. The two wildcard 
 * characters are almost always more than enough to carry out any search required 
 * and is usually much easier to use than some complex regular expressions. If 
 * <b>false</b> is supplied to this optional parameter then it paves the way for 
 * a Regular Expression to be used (or not used) within the search criteria string 
 * and the search is case sensitive unless the regular expression <b>"(?i)"</b> 
 * prefixes the search criteria string. If endorseWildcards is true then upper or 
 * lower letter case is ignored as well (the search is not case sensitive).
 * 
 * @return ({@code List<String>}) A List of desired columnar data found.
 */
public static List<String> searchSelectedTableRows(JTable table,
                                    int searchInColumn,
                                    String searchCriteria,
                                    int returnDataInColumnNumber,
                                    boolean... endorseWildcards) {
    boolean endorseCards = true;
    if (endorseWildcards.length > 0) {
        endorseCards = endorseWildcards[0]; 
    }

    List<String> result = new ArrayList<>();

    String criteria = searchCriteria;
    if (endorseCards) {
        criteria = "(?i)" + criteria.replace("?", ".?").replace("*", ".*?");
    }
    int[] rows = table.getSelectedRows();

    DefaultTableModel dtm = (DefaultTableModel) table.getModel();
    for (int i = 0; i < rows.length; i++) {
        String columnCellValue = dtm.getValueAt(rows[i], searchInColumn - 1) != null
                                 ? dtm.getValueAt(rows[i], searchInColumn - 1).toString() : "";
        if (columnCellValue.matches(criteria)) {
            String res = dtm.getValueAt(rows[i], returnDataInColumnNumber - 1) != null
                                 ? dtm.getValueAt(rows[i], returnDataInColumnNumber - 1).toString() : "";
            result.add(res);
        }
    }
    return result;
}

如何使用上述方法:

List<String> results = searchSelectedTableRows(MyClass.MyTable, 2, jTextField1.getText(), 4);
StringBuilder sb = new StringBuilder();
for (String str : results) {
    sb.append(str).append(System.lineSeparator());
}
// Note that JTextArea is used in case
// there is more than one found record.
jTextArea1.setText(sb.toString());

方法#2:

/**
 * This method will search the supplied JTable for the supplied Criteria String 
 * and return a List of found rows and their respective columnar data delimited 
 * with the Pipe ( | ) character. The search criteria can be played against all 
 * columns in a row or against a specific column if a column number is supplied 
 * within the optional <b>byColumnNumber</b> parameter.<br><br>
 * 
 * <b>Example Usage:</b><pre>
 *    
 *     // Locate the record(s) that contains "My Search Criteria" within the
 *     // 2 column of each record.
 *    {@code List<String> results = searchJTable(MyClass.myJTableName, "?y*sear*ter??", 2);}
 * 
 * @param table (JTable) The JTable variable name.<br>
 * 
 * @param searchCriteria (String) The search criteria string. The specific data 
 * to search for. You can also utilize the <b>?</b> and <b>*</b> wildcard 
 * characters within your search criteria string to make your search as wide 
 * as you like. You can even utilize a Regular Expression for your search 
 * criteria string providing you supply boolean <b>false</b> to the optional 
 * <b>endorseWildcards</b> parameter.<br><br>
 * 
 * @param options (optional - Integers/Boolean):<pre>
 * 
 *      byColumnNumber   - (Integer) Default is 0 (All Columns) If a column 
 *                         number is to be supplied then you must realize that 
 *                         it is the literal column number. This means that 
 *                         the first column in a JTable is 1, not 0.
 * 
 *      endorseWildcards - (boolean) Default is true (allow wildcards). If true 
 *                         then when a wildcard character is encountered within
 *                         a search criteria string it is automatically converted
 *                         to its RegEx equivalent. The two wildcard characters 
 *                         are almost always more than enough to carry out any 
 *                         search required and is usually much easier to use than 
 *                         some complex regular expressions. If endorseWildcards
 *                         is true then upper or lower letter case is ignored as
 *                         well.
 * 
 *                         If you provide a true of false to this parameter then
 *                         you must provide a value (or null) to the option 
 *                         <b>byColumnNumber</b> parameter.</pre>
 * 
 * @return ({@code List<String>}) Because it is possible that more than one record 
 * could be found in a table that matches the search criteria, a List Interface is 
 * used to hold the found records. This List is then returned.
 */
public static List<String> searchJTable(JTable table,
                                        String searchCriteria,
                                        Object... options) {
    // Determine optional parameters.
    int column = -1;
    boolean endorseWildcards = true;
    if (options.length > 0) {
        if (options[0] != null) {
            column = (int)options[0] - 1;
            if (column < 0) { column = -1; }
        }
        if (options.length >= 2) {
            if (options[1] != null) {
                endorseWildcards = (boolean) options[1];
            }
        }
    }

    List<String> results = new ArrayList<>(); // List to hold found results
    String criteria = searchCriteria;
    if (endorseWildcards) {
        criteria = "(?i)" + criteria.replace("?", ".?").replace("*", ".*?");
    }

    int row = table.getSelectedRow();

    DefaultTableModel dtm = (DefaultTableModel) table.getModel();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < dtm.getRowCount(); i++) {
        sb.delete(0, sb.capacity());
        boolean found = false;
        for (int y = 0; y < dtm.getColumnCount(); y++) {
            String columnCellValue = (dtm.getValueAt(i, y) != null
                                      ? dtm.getValueAt(i, y).toString() : "");
            sb.append(sb.toString().equals("") ? columnCellValue : " | " + columnCellValue);
            if ((column > -1 ? columnCellValue.matches(criteria) && y == column : 
                               columnCellValue.matches(criteria))) {
                found = true;
            }

        }
        if (found) {
            results.add(sb.toString());
        }
    }
    return results;
}

如何使用上述方法:

List<String> results = searchJTable(MyClass.MyTableName, jTextField1.getText(), column);
StringBuilder sb = new StringBuilder();
for (String str : results) {
    sb.append(str).append(System.lineSeparator());
}
// Note that JTextArea is used in case
// there is more than one found record.
jTextArea1.setText(sb.toString()); 

推荐阅读