【问题标题】:Search a JTable repeatedly using JTextfield text使用 JTextfield 文本重复搜索 JTable
【发布时间】:2012-07-27 13:20:31
【问题描述】:

以下代码将从文本字段中获取文本并在 JTable 中搜索它。它仅显示文本的第一次出现。我也需要连续发生。所以,请指导我如何实现这一目标。提前致谢。

private void search8()
{
    String target8 = sear8.getText();
    for(int row = 0; row < table8.getRowCount(); row++)
        for(int col = 0; col < table8.getColumnCount(); col++)
        {
            String next8 = (String)table8.getValueAt(row, col);
            if(next8.equals(target8))
            {
                showSearchResults(row, col);
                return;
            }
        }
}

更新:

private void showSearchResults(int row, int col)
{
    CustomRenderer renderer = (CustomRenderer)table8.getCellRenderer(row, col);
    renderer.setTargetCell(row, col);
    Rectangle r8 = table8.getCellRect(row, col, false);
    table8.scrollRectToVisible(r8);
    table8.repaint();
}

class CustomRenderer implements TableCellRenderer
{
    public CustomRenderer()
    {
       label = new JLabel();
       label.setHorizontalAlignment(JLabel.CENTER);
       label.setOpaque(true);
       targetRow = -1;
       targetCol = -1;
    }

    public Component getTableCellRendererComponent(JTable table,
    Object value,boolean isSelected,boolean hasFocus,int row, int column)
    {
       if(isSelected)
       {
           label.setBackground(table.getSelectionBackground());
           label.setForeground(table.getSelectionForeground());
       }
       else
       {
           label.setBackground(table.getBackground());
           label.setForeground(table.getForeground());
       }
       if(row == targetRow && column == targetCol)
       {
           label.setBackground(new Color(176,196,222));
           //label.setBorder(BorderFactory.createLineBorder(Color.red));
           label.setFont(table.getFont().deriveFont(Font.BOLD));
       }
       else
       {
           label.setBorder(null);
           label.setFont(table.getFont());
       }
       label.setText((String)value);
       return label;
    }

    public void setTargetCell(int row, int col)
    {
       targetRow = row;
       targetCol = col;
    }
} 

【问题讨论】:

  • “连续发生”是什么意思?您是希望一次仅突出显示一个实例并要求用户选择“下一个”,还是要同时显示所有实例?
  • @MadProgrammer 用户必须选择下一个
  • @MadProgrammer 对我来说都可以,先生。
  • @MadProgrammer 我尝试使用数组存储值,先生。我已经更新了问题中的代码。但是我得到了数组索引超出范围的异常。先生,我犯了什么错误?
  • @Sujay 感谢您清理格式混乱 :-) 致 OP:此站点在格式代码中存在用于缩进的包含制表符(或更糟:制表符和空格的混合)的问题,所以请不要根本不使用标签。

标签: java swing


【解决方案1】:

在找到 target8 的第一个匹配项后立即返回。

最好建立一个匹配字符串列表并传递给您的方法showSearchResults

【讨论】:

  • 我尝试使用数组存储值,先生。我已经更新了问题中的代码。但我得到数组索引超出范围异常。先生,我犯了什么错误?我是初学者。
【解决方案2】:

有两种方法可以实现:

  • 按照 Reimeus 的建议,执行一次解析以查找特定搜索关键字的所有出现并将其位置存储在列表中。然后调用您的showSearchResults() 并遍历列表。

  • 第二个选项是将您上次扫描的位置存储在某个位置。然后当用户按下下一步时,从这个位置开始搜索,而不是再次(0,0)。

我个人更喜欢第一个选项,因为我不必重复扫描此表。此外,此列表将帮助我非常轻松地实现“上一个”和“下一个”功能

编辑:这是实现这一目标的一种方式(请注意,您必须根据自己的要求对其进行自定义,这只是为了帮助您入门):

private void search8() {
    ArrayList<String> resultList = new ArrayList<String>();

    String target8 = sear8.getText();
    for (int row = 0; row < table8.getRowCount(); row++) {
        for (int col = 0; col < table8.getColumnCount(); col++) {
            String next8 = (String) table8.getValueAt(row, col);
            if (next8.contains(target8)) {
                resultList.add(row + "," + col);
            }
        }
    }

    System.out.println(sarr8.length);

    String[] tokens;
    for (String result : resultList) {
        try {
            tokens = result.split("[,]");
            showSearchResults(tokens[0], tokens[1]);
        } finally {
            tokens = null;
        }
    }

    /**
     * Your remaining part
     */
}

【讨论】:

  • 我尝试使用数组存储值,先生。我已经更新了问题中的代码。但我得到数组索引超出范围异常。先生,我犯了什么错误?我是初学者。
【解决方案3】:
// I'd, personally, make this protected as you may wish to change the how the search 
// is performed in the future.
protected void search8() {

    // You've assumed that there are only ever 40 elements
    // while you've allowed for a variable number of search positions
    // You would need (at least) (rowCount * colCount) * 2 elements to be
    // safe.  This is a little ridiculous considering that there might
    // only be 1 reuslt in the table
    // int[] sarr8 = new int[40]; <-- Don't really want to do this

    // Instead, we should use a dynamic array instead
    // The ArrayList is a Collection implementation backed by an array
    // but it has the means to grow (and shrink) to meet the capacity requirements
    List<Point> slist8 = new ArrayList<Point>(25); // <-- you could change the initial value as you see fit
    int i = 0;
    String target8 = sear8.getText();
    for (int row = 0; row < table8.getRowCount(); row++) {
        for (int col = 0; col < table8.getColumnCount(); col++) {
            String next8 = (String) table8.getValueAt(row, col);
            if (next8.contains(target8)) {
                // Okay, this kinda cheating, but we want to store col/row or x/y
                // cell coordinates.  You could make your own class "Cell" class,
                // but for what we want, this is exactly the same
                Point cell = new Point(col. row);
                //sarr8[i] = row;
                //sarr8[i + 1] = col;
                //i = i + 2;
                slist8.add(cell);
            }
        }
    }

    //System.out.println(sarr8.length);
    System.out.println(slist8.size());

    //for (int j = 0; j < sarr8.length; j += 2) {
    //    showSearchResults(sarr8[j], sarr8[j + 1]);
    //    return;
    //}

    // Now, personally, I'd pass in the whole result set to the "showSearchResults"
    // method, because, IMHO, that's the methods domain of responsibility, ours was
    // to simply find the results.

    showSearchResults(slist8);

    // At this point, the showSearchResults method can determine how it wants to display
    // the search results

}

@Sujay 在他的回答中也演示了这种方法

更新

for (Point p : slist8) {
    showSearchResults(p.x, p.y);
}

其他

private void showSearchResults(List<Point> results)
{

    for (Point p : results) 
    {
        int col = p.x;
        int row = p.y;
        CustomRenderer renderer = (CustomRenderer)table8.getCellRenderer(row, col);
        renderer.setTargetCell(row, col);
        Rectangle r8 = table8.getCellRect(row, col, false);
        table8.scrollRectToVisible(r8);
    }
    table8.repaint();
}

【讨论】:

  • 这是一个很好的解释,先生!太感谢了。但是,我有一个疑问。我已经更新了我的 showSearchResults 方法。它接受两个输入行和列。如果我们发送一个点列表,如何在函数中划分它,Sir?对不起,如果我问的是愚蠢的问题先生。
  • 抱歉,Point 有两个属性,x 和 y。如果您不想自己传递 Point 对象,则可以在列表中存储一个 int 数组(int[])
  • 考虑到我将它们作为积分传递,我应该如何在函数 Sir 中将其拆分?还是修改?
  • 非常感谢,先生。当我运行它时,所有内容都会快速突出显示并消失。只有最后一次出现才会突出显示。为什么先生?如果我没有突出显示每一个事件,我会犯什么错误?我想我一定是在 CustomRenderer 中犯了错误。先生,我说得对吗?
  • 我有一条线 table8.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 。我把它注释掉了。但是,没有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 2013-12-04
  • 2021-03-04
  • 2018-04-23
  • 1970-01-01
相关资源
最近更新 更多