2016-04-05 7 views
0

Я использую JTable внутри JScrollPane с настраиваемой функцией TableModel, выделение ячейки/столбца и включение только выбора строки (единственный выбор). Если я выбираю строку, время от времени, значение в ячейке, в которой я выполняю клик, также отображается в соседних столбцах (и перезаписывает значения там). Может ли кто-нибудь дать мне подсказку, что я делаю неправильно или кто-то другой столкнулся с этой проблемой?Странное поведение JTable при выборе строк

Спасибо за вашу помощь заранее!

EDIT: Я добавил SSCCE. После нескольких выборов проблема должна произойти. Вы можете ускорить его появление, удерживая нажатой кнопку мыши, нависая над строками. Если это произошло один раз, это происходит во время каждого выбора.

import java.awt.BorderLayout; 
import javax.swing.JFrame; 
import javax.swing.JScrollBar; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.ListSelectionModel; 
import javax.swing.WindowConstants; 
import javax.swing.table.DefaultTableModel; 

public class TableIssueSSCCE { 

    public TableIssueSSCCE() { 
     JFrame frame = new JFrame(); 
     frame.setSize(400, 400); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.setLayout(new BorderLayout()); 

     JTable table = new JTable(new DefaultTableModel()); 
     DefaultTableModel model = (DefaultTableModel) table.getModel(); 
     model.addColumn("Test1"); 
     model.addColumn("Test2"); 
     model.addColumn("Test3"); 
     model.addColumn("Test4"); 
     for (int i = 0; i < 1000; i++) { 
      model.addRow(new String[]{ 
       "Column1" + i, "Column2" + i, "Column3" + i, "Column4" + i}); 
     } 

     table.setFillsViewportHeight(true); 
     table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     table.setCellSelectionEnabled(false); 
     table.setColumnSelectionAllowed(false); 
     table.setRowSelectionAllowed(true); 
     table.setAutoCreateRowSorter(true); 
     JScrollPane tableContainer = new JScrollPane(table); 
     tableContainer.setVerticalScrollBar(new JScrollBar(JScrollBar.VERTICAL)); 
     tableContainer.setHorizontalScrollBar(new JScrollBar(JScrollBar.HORIZONTAL)); 
     frame.add(tableContainer, BorderLayout.CENTER); 

     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     new TableIssueSSCCE(); 
    } 
} 
+1

У вас есть код, который изменяет поведение по умолчанию в таблице? Любые слушатели, CellEditors, CellRenderers и т. Д.? – f1sh

+0

'с пользовательским TableModel' - может быть, TableModel ошибается? Попробуйте использовать DefaultTableModel с тем же выбором строки/столбца и посмотреть, что произойдет. Это базовая технология отладки. Сначала попробуйте код с классами по умолчанию. Тогда, если ваш пользовательский код не работает, вы знаете, где проблема. То же самое с вышеуказанными предложениями. Сначала используйте рендеринг по умолчанию. Затем измените одну вещь за раз, пока проблема не возникнет, поэтому вы знаете, какое изменение вызвало проблему. – camickr

+0

Добро пожаловать в StackOverflow! Спасибо за заявку! При размещении вопросов о ошибках кода, пожалуйста, укажите части кода, которые имеют отношение к вопросу. – gariepy

ответ

1

Я смог избежать проблемы, перейдя на JRE Oracle. Поэтому этот вопрос, похоже, связан с OpenJDK.

1

Некоторые наблюдения:

  • Всякий раз, когда программа Свинг периодически ведет себя плохо, я начинаю искать некорректной синхронизации, иногда прибегая к подходу, показанному here. См. Также Initial Threads. Поскольку такие ошибки могут быть трудно воспроизвести, это лучше перестраховаться:

    public static void main(String[] args) { 
        EventQueue.invokeLater(() -> { 
         new TableIssueSSCCE(); 
        }); 
    } 
    
  • Вместо setSize(), переопределить getPreferredScrollableViewportSize(), как это было предложено here.