动态加载 JTable 后,在选定的 JComboBox 出现之前

Upon loading JTable dynamically, before selected JComboBox appears visible

我使用:

我有 JTable,内容在运行时动态加载。它有一些 JComboBoxes。如果我 select JComboBox,然后尝试重新加载 table,则 JComboBox 在 table 加载过程中显示可见。

除此之外,如果 JComboBox 的内容得到更新(在不同 table 的其他地方,当组合应该反映新内容时),新内容在动态加载 JTable 后不会立即可见。

应用快照示例:

也就是说,table 在运行时加载,在中间你有 vsisble JComboBox 从以前的 selection.

如何:

我有 public final class TableColumnEditor extends DefaultCellEditor{ returns 特定列上的 JComboBox:

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:

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

table 在这里动态加载(删除了非必要的东西):

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) {

    }
}

你怎么看?

好吧,我想出了解决这个问题的方法。 首先,JComboBoxEDT(Event Despatch Thread).

上更新
/**
 * @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; 
        }

但主要的修复方法如下,如果没有它,这两个问题都不会消失。 也就是说,我注意到为了让数据立即出现在 table 下,首先,您需要 select 任何其他不相关的 table 的单元格。

也就是运行时加载JTable的Java线程,确实需要这样:

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

这可能是个技巧,但对我有用!