Вызов JComboBox # addItem () в цикле while (resultSet.next ()) заканчивается только одним элементом - PullRequest
2 голосов
/ 17 июня 2011

это код, который вызывает у меня проблемы.

try{
ResultSet rs = Main.dbase.search("select * from myTable");
//rs.next()
while(rs.next())
{
 cmb.addItem(rs.getString(1).trim());
}
rs.close();
} catch (Exception ex) {System.out.println(ex);}

здесь dbase - это объект, выполняющий Statement.executeQuery, а cmb - это JComboBox.

проблема в том, что, хотя таблица имеет 10 строк, я получаю только одну строку в cmb. если я не закомментирую первый rs.next () , я получу 2-ю строку в cmb.

Я попытался отследить значение rs.next () и обнаружил, что после while (rs.next ()) всегда выдает false,

Моя цель - получить все 10 значений в cmb. Как бы я ни исследовал, этот код должен добавить все значения в cmb, но добавляется только одно значение. если перед входом в цикл я вызываю rs.next () , то следующее значение добавляет к cmb.

Ответы [ 3 ]

2 голосов
/ 17 июня 2011

Вы не упомянули, было ли исключение обнаружено вашим блоком catch.

То, что я вижу, может помешать продвижению цикла дальше первой строки, так это то, что в следующей строке будет NULL первый столбец.

Действительно, если в 1-м столбце любой из строк, возвращаемых "select * from myTable", есть NULL, то rs.getString(1).trim() выдаст NullPointerException, что прервет цикл.

Вы можете избежать этого, написав:

try {
    ResultSet rs = Main.dbase.search("select * from myTable"); 
    while(rs.next()) {
        String result = rs.getString(1);
        if (result != null) {
            result = result.trim();
        }
        cmb.addItem(result);
    } 
    rs.close();
} catch (Exception ex) {
    System.out.println(ex);
} 

Кроме того, я бы улучшил весь фрагмент кода, чтобы:

  • убедитесь, что rs закрыто, даже если возникает исключение
  • убедитесь, что мы видим полную трассировку стека любого исключения
  • убедитесь, что cmb обновляется исключительно из EDT (правило Swing EDT)
  • избегайте слишком большого количества вызовов в EDT путем агрегирования всех addItems в целом

Тогда вот что у вас будет:

ResultSet rs = null; 
try {
    final List<String> allItems = new ArrayList>String>();
    rs = Main.dbase.search("select * from myTable"); 
    while(rs.next()) {
        String result = rs.getString(1);
        if (result != null) {
            result = result.trim();
        }
        allItems.add(result);
    }
    SwingUtilities.invokeLater(new Runnable() {
        @Overrive public run() {
            for (String item: allItems) {
                cmb.addItem(item);
            }
        }
    });
} catch (Exception ex) {
    ex.printStacktrace();
} finally {
    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Конечно, некоторые части еще можно улучшить, например, я бы написал вспомогательный метод для закрытия ResultSet, если это не null, потому что этот код, вероятно, будет многократно использоваться во многих местах.

1 голос
/ 17 июня 2011

Если ваш ResultSet действительно заполнен правильно, то ваша проблема с Swing. То есть Swing не является потокобезопасным. При добавлении элементов в JComboBox крайне важно, чтобы вы делали это в потоке отправки событий или EDT. Для этого используйте служебный класс SwingUtilities, чтобы опубликовать задачу Runnable на EventQueue, которая будет выполняться в EDT. Например,

while(rs.next()){
    if(SwingUtilities.isEventDispatchThread()){
        cmb.addItem(rs.getString(1).trim());
    }
    else{
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                cmb.addItem(rs.getString(1).trim());
            }
        });
    }
}

Независимо от того, что на самом деле является проблемой, прислушайтесь к этому совету.

0 голосов
/ 17 июня 2011

Это правильная структура того, что вы делаете, поэтому проблема, вероятно, кроется в другом.SELECT * не очень хорошая идея в такой ситуации, и SELECT * в сочетании с rs.getString(1) делает невозможным повторное предположение, что добавляется в поле со списком.Я собираюсь догадаться, что первая колонка не то, что вы думаете.По крайней мере, используйте rs.getString("column_name_I_want").

Кстати, вы уверены, что хотите search, а не какой-то execute?

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