После динамической загрузки JTable выбранный JComboBox отображается видимым - PullRequest
0 голосов
/ 12 апреля 2020

Я использую:

  • Java 10 SE
  • Java Swing
  • Eclipse IDE

У меня есть JTable содержимое загружается во время выполнения динамически. У него есть несколько JComboBox. Если я выбираю JComboBox, а затем пытаюсь перезагрузить таблицу, JComboBox появляется видимым во время загрузки таблицы.

Кроме того, если содержимое JComboBox обновляется (в другом месте другой таблицы, когда комбо должно отражать это новое содержимое), это новое содержимое не становится видимым сразу после динамической загрузки JTable.

Образец моментального снимка приложения: enter image description here

То есть таблица загружается во время выполнения, и в середине у вас есть постоянный vsisble JComboBox из предыдущего выбора.

Как:

  • Избавьтесь от этого постоянного JComboBox
  • Сделайте данные видимыми мгновенно, после обновления под комбо, как только вы загрузите таблицу динамически

У меня есть public final class TableColumnEditor extends DefaultCellEditor{, который возвращает JComboBox для указанного столбца c:

else if(row == ROW_2_DEVS_WORK_WEEKEND) {
            ProjectMetrics metrics = new ProjectMetrics();
            JComboBox<String> combo = new JComboBox<>();
            combo.setBackground(Color.WHITE);   

            for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
                combo.addItem(devs);
            }

            return combo;
        }

У меня есть public final class TableColumnRenderer extends DefaultTableCellRenderer{, который гарантирует, что представление отображает JComboBox с указанным значением * 10 49 * колонка:

else if(row == ROW_2_DEVS_WORK_WEEKEND) {
            ProjectMetrics metrics = new ProjectMetrics();
            JComboBox<String> combo = new JComboBox<>();
            combo.setBackground(Color.WHITE);   

            for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
                combo.addItem(devs);
                break;
            }

            return combo;
        }

Таблица загружается динамически прямо здесь ( ненужные вещи удалены ):

public static void reloadTableDynamically(JTable metricsTable){

    DefaultTableModel model = (DefaultTableModel)metricsTable.getModel();

    if(projectData.isEmpty()) {         
        metricsTable.clearSelection();

        int rowCount = model.getRowCount();
        for(int item = (rowCount - 1); item >= 0; item--) {
            model.removeRow(item);//clears previous rows    
        }

        metricsTable.repaint();                                 
        return; 
    }

    model.getDataVector().clear();      
    int rowCount = constantRows + ((devsTask.size() == 0) ? 1 : devsTask.size());

    try {
        new Thread(()-> {   
            int lastRowID = 0;
            int devsTaskID = 0;

            for(int item = 0; item < rowCount; item++) {                                        
                Object[] input = null;
                if(item == 0) {
                    input = new Object[] {"", metrics.getProjectDateRange(), "" };
                }//similar branches removed
                else {
                    devsTaskID++;
                    input = new Object[] {"", devsTask.get(devsTaskID).getDeveloper(), ""};
                }

                model.addRow(input);
                metricsTable.scrollRectToVisible(new java.awt.Rectangle(metricsTable.getCellRect(lastRowID++, 0, true)));
                metricsTable.repaint();

                try {
                    Thread.sleep(Config.getInstance().getReloadInOutTable());
                }
                catch(InterruptedException e) {
                    e.printStackTrace();
                }
            }

            metricsTable.scrollRectToVisible(new java.awt.Rectangle(metricsTable.getCellRect(projectData.size() - 1, 0, true)));
            metricsTable.repaint();//so that to reach the last row

        }).start();
    }
    catch(Exception e) {

    }
}

Что вы думаете?

1 Ответ

0 голосов
/ 13 апреля 2020

Ну, я разобрался, как преодолеть эту проблему. Во-первых, JComboBox обновляется в EDT ( Поток отправки событий ).

/**
 * @param combo The JComboBox ref.
 * @param toDisplay The value to add to it
 */
public static void updateComboBoxOnEventDespatchThread(JComboBox<String> combo, String toDisplay) {
    Runnable doComboUpdate = new Runnable() {
         public void run() { 
             combo.addItem(toDisplay);
         }
     };

     SwingUtilities.invokeLater(doComboUpdate);
}

В редакторе столбцов JTable:

else if(row == ROW_2_DEVS_WORK_WEEKEND) {
            ProjectMetrics metrics = new ProjectMetrics();

            JComboBox<String> combo = new JComboBox<>();
            combo.setBackground(Color.WHITE);

            Runnable doComboInsert = new Runnable() {
                public void run() { 
                    int id = 0;
                    for(String devs : metrics.identifyDevsThatWorkAtWeekend()) {
                        UIutils.updateComboBoxOnEventDespatchThread(combo, "("+ ++id +") " + devs);
                    }                           
                }
            };

            SwingUtilities.invokeLater(doComboInsert);
            return combo; 
        }

Но главное исправление, без которого не устраняются обе проблемы, заключается в следующем. То есть я заметил, что для того, чтобы данные появлялись под таблицей мгновенно, во-первых, вам нужно выбрать ячейку любой другой несвязанной таблицы.

То есть поток Java, который загружает JTable во время выполнения , нужно иметь это:

if(model.getRowCount() > 0) {
        metricsTable.selectAll();
    }

Это, вероятно, взломать, но это работает для меня!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...