Java JTable 转到行错误

发布于 2024-10-10 19:51:16 字数 2394 浏览 3 评论 0原文

我有一个 find 函数,可以在包含数千个条目的 JTable 中查找字符串。 Michael Meyers 非常友善地帮助我解决了该函数的 goto 部分。但似乎存在一个错误...

当用户搜索字符串时,应用程序正确地找到 JTable 中的行并突出显示它。它也试图关注它,但并不总是如此。有时它会跳到比我要查找的行短 10 行以上,我需要向下滚动才能看到它。正如我所说,此 JTable 中有几千个条目,如果我要搜索某些内容,则很难滚动。 是否可以将所选条目聚焦在可见区域的中心?

if (logs.get(i).getLine().contains(findStr))
{
    logTable.scrollRectToVisible(logTable.getCellRect(thisPos, 1, true));   // goto
    logTable.setRowSelectionInterval(thisPos, thisPos);                     // highlight
}

我不确定它是否有帮助,但这里是 JTable 设置代码:

JTable logTable = new JTable(logTableModel);
logTable.setShowGrid(true);
logTable.setShowVerticalLines(true);
logTable.setShowHorizontalLines(false);
logTable.setRowSorter(sorter);
logTable.getSelectionModel().addListSelectionListener(new LogRowListener());

JScrollPane scrollPane = new JScrollPane();
scrollPane.getViewport().add(logTable);
scrollPane.setPreferredSize(new Dimension(800, 450));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

谢谢

编辑 以下是下载 .jar 文件的链接。该文件是说明问题的代码的有限版本。这个版本似乎总是短跳 2-3 行,但完整版本中情况并非总是如此。

Demo.jar

即使这个演示的代码仍然有几百行,所以下面是我认为相关的部分。

public class Proto extends JFrame implements ActionListener
{
    public Proto() { ... }

    @Override
    public void actionPerformed(ActionEvent event) 
    {
        String command = event.getActionCommand();

        if (BUTTON_NEXT_FIND.equals(command)) 
        {
            findNext();
        }
    }

    ...        

    private void findNext()
    {
        String findStr = findField.getText();

        int pos = selectedLogRow;

        // if we're searching for the same string again step forward once
        if (pos == lastFoundPos)
            ++pos;

        // search through the log for the string 
        while (pos < logs.size())
        {
            if (logs.get(pos).getLine().contains(findStr))
            {
                logTable.scrollRectToVisible(logTable.getCellRect(pos, 1, true));
                logTable.setRowSelectionInterval(pos, pos);
                lastFoundPos = pos;
                break;    
            }
            ++pos;
        }
    }

    ...
}

I have a find function that locates a string in a JTable with quite a few thousand entries. Michael Meyers was kind enough to help me out with the goto portion of the function. There appears to be a bug though...

When the user searches for the string the application correctly finds the line in the JTable and highlights it. It also attempts to focus on it, but does not always. Sometimes it will jump 10+ lines short of the line I am looking for and I need to scroll down to see it. As I said, there are a few thousand entries in this JTable and if I'm searching for something, it's difficult to scroll around. Is it possible to focus the selected entry in the center of the visible area?

if (logs.get(i).getLine().contains(findStr))
{
    logTable.scrollRectToVisible(logTable.getCellRect(thisPos, 1, true));   // goto
    logTable.setRowSelectionInterval(thisPos, thisPos);                     // highlight
}

I'm not sure that it helps any, but here is the JTable setup code:

JTable logTable = new JTable(logTableModel);
logTable.setShowGrid(true);
logTable.setShowVerticalLines(true);
logTable.setShowHorizontalLines(false);
logTable.setRowSorter(sorter);
logTable.getSelectionModel().addListSelectionListener(new LogRowListener());

JScrollPane scrollPane = new JScrollPane();
scrollPane.getViewport().add(logTable);
scrollPane.setPreferredSize(new Dimension(800, 450));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

Thanks

EDIT
Below is a link to download a .jar file. This file is a limited version of the code that illustrates the problem. This version seems to consistently jump 2-3 lines short, that is not always the case in the full version.

Demo.jar

The code even for this demo is still a few hundred lines, so below is the sections that I believe are relevant.

public class Proto extends JFrame implements ActionListener
{
    public Proto() { ... }

    @Override
    public void actionPerformed(ActionEvent event) 
    {
        String command = event.getActionCommand();

        if (BUTTON_NEXT_FIND.equals(command)) 
        {
            findNext();
        }
    }

    ...        

    private void findNext()
    {
        String findStr = findField.getText();

        int pos = selectedLogRow;

        // if we're searching for the same string again step forward once
        if (pos == lastFoundPos)
            ++pos;

        // search through the log for the string 
        while (pos < logs.size())
        {
            if (logs.get(pos).getLine().contains(findStr))
            {
                logTable.scrollRectToVisible(logTable.getCellRect(pos, 1, true));
                logTable.setRowSelectionInterval(pos, pos);
                lastFoundPos = pos;
                break;    
            }
            ++pos;
        }
    }

    ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

好多鱼好多余 2024-10-17 19:51:16

有时它会跳到比我要查找的行短 10 多行,我需要向下滚动才能看到它。

发布您的 SSCCE 来演示该问题。您可以创建一个包含一千行的表,然后使用 setValueAt(...) 方法用您要搜索的文本填充一些随机单元格。

是否可以将所选条目聚焦在可见区域的中心?

您需要调整要滚动到的行号。也就是说,如果您向下搜索,则需要从行号中减去“x”,以便视口位于包含文本的行之前的一行上。

Sometimes it will jump 10+ lines short of the line I am looking for and I need to scroll down to see it.

Post your SSCCE that demonstrates the problem. You can just create a table with a thousand rows and then use setValueAt(...) method to populate a few random cells with the text you are searching for.

Is it possible to focus the selected entry in the center of the visible area?

You need to adjust the row number you want to scroll to. That is if you are searching down you would need to subtract "x" from the row number so the viewport is position on a row before your row that contains the text.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文