2016-12-26 3 views
1

Я использую JTable для отображения данных. Когда строка выбирается программно, она должна (автоматически) прокручивать эту строку в виде, чтобы она была первой строкой сверху. Для этого у меня есть следующий метод:Прокрутите до выбранной строки правильно для JTable

private static void scrollToSelectedRow(JTable table) 
{ 
    JViewport viewport = (JViewport) table.getParent(); 
    Rectangle cellRectangle = table.getCellRect(table.getSelectedRow(), 0, true); 
    Rectangle visibleRectangle = viewport.getVisibleRect(); 
    table.scrollRectToVisible(new Rectangle(cellRectangle.x, cellRectangle.y, (int) visibleRectangle.getWidth(), (int) visibleRectangle.getHeight())); 
} 

Проблема заключается в том, что вызов это может или не может прокручиваться правильно, например, выбранная строка может быть сверху или не недетерминированно. Для того, чтобы исправить это, я пытался вызвать метод дважды с задержкой между ними, а также перекрашивать его:

public static void setSelectedRow(JTable table, int rowIndex, int columnIndex) 
{ 
    table.setRowSelectionInterval(rowIndex, columnIndex); 
    scrollToSelectedRow(table); 
    try 
    { 
     Thread.sleep(100); 
    } catch (InterruptedException exception) 
    { 
     exception.printStackTrace(); 
    } 
    scrollToSelectedRow(table); 
    table.repaint(); 
} 

Это работает намного лучше, но до сих пор иногда глюки столбцы таблицы из так, видимо, это не умный чтобы остановить EDT, пока он обновляется. Появляется вызов repaint(), чтобы предотвратить перекрытие строк аналогичным образом. Графические сбои можно легко устранить, перемещая мышь по затронутым строкам/столбцам, хотя это не должно происходить.

Как я могу выполнить прокрутку без ожидания и без графических сбоев?

ответ

2

Код выглядит разумным. Обычно трюк заключается в том, чтобы ширина/высота прямоугольника была размером окна просмотра, чтобы заставить свиток.

Две мысли.

  1. Избавьтесь от Thread.sleep(). все, что будет сделано, это не позволить графическому интерфейсу перерисовывать себя на 100 мс.

  2. Попробуйте обернуть scrollRectToVisible(...) в SwingUtlities.invokeLater(...).

Если точка 2 не помогает, разместите надлежащую [mcve], которая демонстрирует проблему.

+0

Действительно, ваше второе предложение сделал трюк: 'SwingUtilities.invokeLater (() -> table.scrollRectToVisible (новый прямоугольник (cellRectangle.x, cellRectangle.y (INT) visibleRectangle.getWidth(), (интермедиат) visibleRectangle .getHeight()))); ' – BullyWiiPlaza

Смежные вопросы