2011-01-08 10 views
1

Ich habe eine Suchfunktion, die einen String in einer JTable mit einigen tausend Einträgen findet. Michael Meyers war nett genug, um mir mit dem Goto-Teil der Funktion zu helfen. Es scheint jedoch einen Fehler zu geben ...Java JTable Gehe zu Row Bug

Wenn der Benutzer nach der Zeichenfolge sucht, findet die Anwendung die Zeile in der JTable korrekt und markiert sie. Es versucht auch, sich darauf zu konzentrieren, aber nicht immer. Manchmal springt es mehr als 10 Zeilen vor der Zeile, nach der ich suche, und ich muss nach unten scrollen, um es zu sehen. Wie gesagt, es gibt ein paar tausend Einträge in dieser JTable und wenn ich nach etwas suche, ist es schwierig herumzublättern. Ist es möglich, den ausgewählten Eintrag in der Mitte des sichtbaren Bereichs zu fokussieren?

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

Ich bin nicht sicher, dass es jeder hilft, aber hier ist die 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); 

Dank

EDIT Unten finden Sie einen Link zum Herunterladen einer. JAR-Datei. Diese Datei ist eine eingeschränkte Version des Codes, der das Problem veranschaulicht. Diese Version scheint regelmäßig 2-3 Zeilen kurz zu springen, das ist in der Vollversion nicht immer der Fall.

Demo.jar

Der Code selbst für diese Demo noch ein paar hundert Zeilen ist, ist so unter die Abschnitte, die ich sind relevant glauben.

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; 
     } 
    } 

    ... 
} 

Antwort

0

Manchmal wird es zu springen 10+ Linien kurz vor der Linie ich suche und ich brauche es, um zu sehen nach unten zu scrollen.

Veröffentlichen Sie Ihre SSCCE, die das Problem veranschaulicht. Sie können einfach eine Tabelle mit tausend Zeilen erstellen und dann die setValueAt (...) -Methode verwenden, um einige zufällige Zellen mit dem gesuchten Text zu füllen.

Ist es möglich, den ausgewählten Eintrag in der Mitte des sichtbaren Bereichs zu fokussieren?

Sie müssen die Zeilennummer anpassen, zu der Sie blättern möchten. Das heißt, wenn Sie nach unten suchen, müssen Sie "x" von der Zeilennummer subtrahieren, damit das Ansichtsfenster in einer Zeile vor Ihrer Zeile steht, die den Text enthält.

+0

Ich habe nicht den gesamten Code veröffentlicht, hätte das Hinzufügen von benutzerdefinierten TableModel und CustomRendorers beteiligt. Aber eine getrimmte Version der Anwendung, um das Problem zu veranschaulichen und die gesamte Suchfunktion veröffentlicht. Es gibt wirklich keinen Code mehr als UI-Zeug, aber lassen Sie mich wissen, wenn Sie etwas anderes wollen. – linsek

+0

@njozwiak, warum müssen Sie ein benutzerdefiniertes TableModel und einen Renderer hinzufügen? Sind sie die Ursache des Problems? Es dauert eine Zeile Code, um eine Tabelle mit 1000 Zeilen zu erstellen: neue JTable (1000, 3); Es werden noch ein paar Zeilen Code benötigt, um einige Werte in verschiedenen Zeilen zu setzen. Dann fügen Sie dem Rahmen die Tabelle hinzu. Dann fügen Sie Ihren Suchknopf und Code hinzu. Die SSCCE sollte etwa 20-30 Zeilen Code umfassen. Sie erstellen das SSCCE für einen Proof of Concept, das scrollRectToVisible() funktioniert so, wie Sie es erwarten. Der Code, den Sie gepostet haben, hilft nicht, da er nicht ausführbar ist. – camickr