2017-02-02 10 views
0

Я разрабатываю классы на основе шаблона DAO.Преобразование списка <ClassName> для объекта массива для установки как JComboBoxModel

У меня есть 3 класса и 1 форма GUI.

public interface SchoolYearDao { 
    List<SchoolYear> getAllSchoolYearInfo(); 
    List<SchoolYear> getAllSchoolYearStart(); 
    List<SchoolYear> getAllSchoolYearEnd(); 
    List<SchoolYear> getSchoolYearById(int aSchoolYearId); 
    int getSchoolYearId(SchoolYear schoolyear); 
    boolean addSchoolYear(SchoolYear schoolyear); 

} 

public class SchoolYear { 
//setters and getters 
} 

public class SchoolYearDaoImpl implements SchoolYearDao{ 
@Override 
    public List<SchoolYear> getAllSchoolYearStart() { 
     List<SchoolYear> listOfSchoolYearStart = new ArrayList<>(); 
     SchoolYear mySchoolYear = new SchoolYear(); 
     String SQL = "{CALL getAllSchoolYearInfo()}"; 

     try(Connection con = DBUtil.getConnection(DBType.MYSQL); 
       CallableStatement cs = con.prepareCall(SQL);) { 
      try(ResultSet rs = cs.executeQuery();){ 
       while(rs.next()){ 
        mySchoolYear.setStart(rs.getInt("yearFrom")); 
       } 
       listOfSchoolYearStart.add(mySchoolYear); 
      } 
     } catch (SQLException e) { 
      JOptionPane.showMessageDialog(null,e.getMessage()); 
     } 
     System.out.println(listOfSchoolYearStart); 
     return listOfSchoolYearStart; 
    } 
} 

Проблема с графическим интерфейсом.

public class SchoolYearGUI extends javax.swing.JPanel { 
    public SchoolYearGUI() { 
     initComponents(); 

     schoolYearStartJcbx.setModel(new DefaultComboBoxModel(schoolyear.getAllSchoolYearInfo().toArray()); 
     schoolYearEndJcbx.setModel(new DefaultComboBoxModel(schoolyear.getAllSchoolYearEnd().toArray())); 
    } 
} 

Я не могу получить годы, чтобы показать их правильно. Я понимаю это.

enter image description here

Вместо действительных целых чисел 2015,2016,2017 и так далее ...

я исследую в Интернете и обнаружил аналогичные проблемы, но большинство из них не использовали список class в List<SchoolYear> , В этом случае «SchoolYear» - это название класса.

Я использовал toArray(); и пробовал Arrays.toString(array);, но не могу понять это правильно. я думал, что изменить тип возвращаемого значения DefaultComboBoxModel из getAllSchoolYearStart() метода, но я понял, что я должен держать мой List<SchoolYear> как типа возвращаемого в случае, если мне нужно использовать набор результатов в качестве модели для JTables и т.д ..

Так , Я хочу просто придерживаться List<SchoolYear> как тип возврата. (Если это хорошая идея?)

Каков наилучший способ получить фактическое значение?

Заранее спасибо.

=============== Решение =========================================================================================================

MadProgrammer за консультацию и другие ответчики.

Итак, я изучил listcellrenderer всю ночь и, наконец, получил общее представление о том, как его использовать.

public MainFrame() { 
     initComponents(); 
     SchoolYearDaoImpl sy = new SchoolYearDaoImpl(); 
     DefaultComboBoxModel model = new DefaultComboBoxModel(sy.getAllSchoolYearStart().toArray()); 
     jcmbSchoolYearStart.setModel(model); 
     jcmbSchoolYearStart.setRenderer(new DefaultListCellRenderer() { 
      @Override 
      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 
       super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 
       if(value instanceof SchoolYear){ 
        SchoolYear schoolyear = (SchoolYear) value; 
        setText(""+schoolyear.getStart()); 
       } 
       return this; 
      } 
     }); 
    } 

Я переопределен в getListCellRendererComponent и создал if-statement, чтобы проверить, если значение является экземпляр моего класса, который является «учебным годом» Тогда я бросил все, что сырье value является учебным годом затем использовал добытчик учебного года модели, getStart(), чтобы получить значение, хранящееся в списке.

Теперь я перемещаю рендеринг в файл внешнего класса в моем проекте.

enter image description here

+3

Проблема в том, как вы выполняете рендеринг (или нет) объекта. По умолчанию 'JComboBox' будет использовать метод' toString' вашего класса для генерации текстового представления. Это, вероятно, самое простое решение, переопределить метод toString и вернуть собственный результат. Лично мне это не нравится, поскольку он блокирует вас одним способом представления объекта, а лучшее решение (IMHO) - предоставить вам собственный пользовательский ListCellRenderer, который может соответствующим образом форматировать объект. – MadProgrammer

+0

Посмотрите на [Как использовать comboboxs, предоставляя собственный рендерер] (https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html#renderer) для получения более подробной информации – MadProgrammer

+0

@MadProgrammer Спасибо за Помогите. Теперь я получаю идею использования рендеринга, который дает большую гибкость. Мне еще предстоит многому научиться, и мне нужно практиковать его с другими элементами GUI. – p3ace

ответ

1

Точно так, как сказал @MadProgrammer, в new DefaultComboBoxModel(schoolyear.getAllSchoolYearInfo().toArray(), вы положили в массив Object с, а конструктор из JComboBox будет пытаться использовать метод toString() преобразовать каждый экземпляр SchoolYear, чтобы представить его как простой текст. Если вы не перезапишите метод по умолчанию toString(), чтобы представить его как хотите, вы увидите, что вы видите в выпадающем списке, которое у вас есть сейчас: имя класса с некоторыми номерами.

Вы можете реализовать метод toString(), но это не самый лучший способ. Вы можете построить некоторый метод утилиты вместе с getSchoolYearId(), который у вас есть, чтобы получить идентификатор каждого объекта в Списке и заполнить массив идентификаторами.

private int[] getIDAndFillAnArray(List<SchoolYear> syrs) { 
    int[] ids = new int[syrs.size()]; 
    for (int i=0; i<syrs.size(); i++) { 
     ids[i] = syrs.get(i).getSchoolYearId(); 
    } 
    return ids; 
} 

И просто использовать его как:

schoolYearStartJcbx.setModel(new DefaultComboBoxModel(getIDAndFillAnArray(schoolyear.getAllSchoolYearInfo())); 

Это достаточно просто.

+0

Спасибо, это тоже помогло. – p3ace

0

Используйте этот класс:

public class ComboItem { 
private String value; 
private String label; 

public ComboItem(String value, String label) { 
    this.value = value; 
    this.label = label; 
} 

public String getValue() { 
    return this.value; 
} 

public String getLabel() { 
    return this.label; 
} 

@Override 
public String toString() { 
    return label; 
} 
} 

Поместите этот метод, когда вы подключаетесь к вашей БД:

public ComboItem[] getListOfSchoolYearStart(params..) 
{ 
List<ComboItem> result = new ArrayList<ComboItem>(); 
ComboItem[] items; 
..... 
    rs = stmt.executeQuery(query); 
      while (rs.next()) { 
       ComboItem item = new ComboItem(rs.getInt("id_school") + "", rs.getString("description")); 
       result.add(item); 
      } 
items = result.toArray(new ComboItem[result.size()]); 

     return items; 
} 

Добавить JComboBox:

private ComboItem[] listOfSchoolYearStart; 
private int selectedIdSchool=-1; 
    .... 
    listOfSchoolYearStart= getListOfSchoolYearStart(); 
    JComboBox comboList = new JComboBox(listOfSchoolYearStart); 

    //If you want to keep previous selection 
      if (listOfSchoolYearStart.length > 0) 
      { 
        boolean isFound=false; 
        for (ComboItem comb : listOfSchoolYearStart) { 
         if(Integer.parseInt(comb.getValue())==selectedIdSchool) 
         { 
          comboList.setSelectedItem(comb); 
          isFound=true; 
          break; 
         } 
        } 
        if(!isFound) 
        { 
         comboList.setSelectedIndex(0); 
        selectedIdSchool=Integer.parseInt(listOfSchoolYearStart[0].getValue()); 
        } 
      } 

Это работает для меня, по крайней мере, Я надеюсь, что это помогает.

+0

Для всего этого, вы можете использовать «ListCellRenderer» – MadProgrammer