Особенности работы с представлением данных и манипуляциями со столбцами в объекте JTable

Автор: content Вторник, Апрель 10th, 2012 Нет комментариев

Рубрика: Язык Java

Данная задача решалась при разработке матрицы планирования эксперимента (МПЭ), которая яв-ляется основным объектом системы исследования свойств порошковых материалов с помощью сим-плекс планов. Вся идеология системы основана на теории планирования эксперимента и математиче-ской статистики. Исходя и этого, МПЭ имеет ряд свойств и методов. В частности она состоит из обяза-тельной части и не обязательной. В обязательную часть входит рис.1:

  1. номер опыта;
  2. относительные (Z1…Z3) и абсолютные (X1,X2,X3) концентрации компонентов смеси;
  3. значение функции отклика (Y1) в соответствующих точка, которые получены в результате про-ведения эксперимента;
  4. значение коэффициентов полинома, которые получаются расчетным путем в зависимости от выбранной модели (b1,b2…,g12,g13….).


Рисунок 1МПЭ — обязательная частьОтсутствие любого компонента обязательной части ведет к потери функциональности МПЭ. На основании данных представленных в МПЭ строятся контурные кривые отклика на симплекс — диаграм-ме. Однако на практике наличие одного отклика не всегда позволяет в полной мере выполнить анализ тех или иных свойств смесей. Самый простой выход – создание аналогичной МПЭ, с теми же концен-трациями, но для другого отклика. Под откликом в данном контексте понимаются некоторые исследуе-мые электрофизические и прочностные характеристики смеси. Однако как показывает тестирование разрабатываемой системы при планировании эксперимента, данный подход не удобен для практическо-го использования. Кроме того, при данном подходе не рационально используются ресурсы ЭВМ, так как создание подобных объектов требует дополнительного выделения памяти. В свою очередь наличие од-ного отклика в МПЭ затрудняет анализ полученных данных, используя критерий Харрингтона (функция желательности). Поэтому возникла задача создать возможность добавления и соответственно удаления в МПЭ дополнительных откликов, а также анализа полученных данных с помощью критерия Харрингто-на.

Следовательно, добавляемые отклики и критерий Харрингтона, можно отнести к необязательной части МПЭ, так как их отсутствие не сказывается на функциональных возможностях МПЭ, а присутст-вие только расширяет их.

Разобьем данную задачу на два этапа, первый этап связан с созданием МПЭ и добавлением столб-цов в нее, а второй соответственно удалением столбцов из нее.

Добавление столбцов

Сам объект МПЭ отображается на экране посредством объекта JinternalFrame в который занесен объект JscrolPane с собственно таблицей, объект JTable. Вопросы создания указанных объектов являют-ся довольно тривиальными, более интересным, с точки зрения дальнейшего использования является способ «наполнения» и создания объекта JTable, так как он в данном случае является основнымКод создания объекта выглядит следующим образом:

…………………………
Vector col = new Vector();
col.addElement(«№  опыта»);
col.addElement(«Координаты»);
col.addElement(«Z1″);
col.addElement(«Z2″);
col.addElement(«Z3″);
col.addElement(«X1″);
col.addElement(«X2″);
col.addElement(«X3″);
col.addElement(«Отклик-Y1″);
col.addElement(«Знач.-Y1″);
col.addElement(«Коэф.-Y1″);
col.addElement(«Знач.Коэф.-Y1″);
dtm = new DefaultTableModel(col,0){
public boolean isCellEditable(int row, int column) {
return true;}
};
jt = new JTable(dtm);
jt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
jsp = new JScrollPane(jt);
………………………………..

Что из этого кода следует? Во – первых, для хранения данных используется DefaultTableModel, столбцы заносятся в модель данных с помощью вектора. Мною был рассмотрен вариант создания таб-лицы, используя, конструктор JTable(TableModel, TableColumnModel). Фрагмент кода альтернативного создания, используя модель столбцов:

…………………
dtcm = new DefaultTableColumnModel();
TableColumn tc1 = new TableColumn();
tc1.setHeaderValue(«№ опыта»);
tc1.setWidth(20);
dtcm.addColumn(tc1);

TableColumn tc2 = new TableColumn();
tc2.setHeaderValue(«Коордтинаты»);
tc2.setWidth(20);
dtcm.addColumn(tc2);
……………

А для модели данных в этом случае используется конструктор :

dtm = new DefaultTableModel(){};

В этом случае, как видно, код создания столбца увеличивается с одной строчки до четырех, по умолчанию создается модель данных с 0-ым количеством столбцов и строк.

Также особое внимание необходимо уделить именованию столбцов, так как в дальнейшем это бу-дет важным фактором при манипуляциях с ними. Для удобства, я принял решение, что название столб-ца характеризующего отклик должно состоять из двух частей, это связано с тем, что, по сути, при до-бавлении отклика в таблицу добавляется четыре столбца: обозначение отклика, значение отклика; ко-эффициенты полинома для данного отклика; значение коэффициентов полинома. Поэтому старшая часть названия должна указывать на тип столбца (Отклик, Знач., Коэф. ЗначКоэф.), а младшая индекс отклика (Y1,Y2….Yn). Поэтому в классе МПЭ создается переменная – индекс и методы setIdx() и getIdx() для работы с ней. Кроме того, в таблицу еще необходимо добавлять два столбца, которые буду отвечать за критерий Харрингтона, особенность их добавления заключается в том, что они добавляются, когда МПЭ имеет один отклик, и при последующих добавлениях откликов, должны располагаться после всех столбцов.

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

int IDx = arPlanCreate.getIdx();
IDx++;
if (dtm.ColumnCount()= =12) {
dtm.addColumn(«Отклик-Y»+ IDx);
dtm.addColumn(«Знач.-Y»+ IDx);
dtm.addColumn(«Коэф.-Y»+ IDx);
dtm.addColumn(«Знач.Коэф-Y»+ IDx);
dtm.addColumn(«Желательность»);
dtm.addColumn(«Знач.Жел.»);
feelOt(12);
arPlanCreate.revalidate();
arPlanCreate.repaint();
}

Или 4-е столбца, но в этом случае необходимо обеспечить размещение столбцов характеризующих функцию желательности в самом конце. Дело в том, что как только столбец добавлен в модель данных, он сразу получает свой порядковый номер, и если предыдущие столбцы не удалялись, то этот номер ос-тается неизменным, следовательно, порядок вывода на экран может не совпадать с порядком следова-ния столбцов в модели данных. Поэтому для изменения порядка следования столбцов на экране, кото-рый не совпадает с моделью данных таблицы, используется метод setChangeColumn():

else{
int colCol = dtm.getColumnCount();
dtm.addColumn(«Отклик-Y»+ IDx);
dtm.addColumn(«Знач.-Y»+ IDx);
dtm.addColumn(«Коэф.-Y»+ IDx);
dtm.addColumn(«Знач.Коэф-Y»+ IDx);
feelOt(colCol++);
int newCol = dtm.getColumnCount();
setChangeColumn();
arPlanCreate.revalidate();
arPlanCreate.repaint();

}
arPlanCreate.setIdx(IDx);

Метод feelOt() позволяет заполнять соответствующие столбцы обозначением отклика и коэффици-ентов.

private void setChangeColumn(){
tcm = arPlanCreate.jt.getColumnModel();
for(int i = 0; i < dtm.getColumnCount();i++){
TableColumn tc = tcm.getColumn(i);
if(tc.getHeaderValue().toString().indexOf(«Жел»)>-1 ){
tcm.moveColumn(i,dtm.getColumnCount()-1);
tcm.moveColumn(i,dtm.getColumnCount()-1);
break;
}
}

}

Удаление столбцов
При удалении столбцов необходимо проверить три условия. Первое условие связано с проверкой выделения столбца и не представляет большого интереса. Второе условие проверя-ет общее количество столбцов в МПЭ, так как, было написано выше, она в результате удаления может потерять свое функциональное назначение. Особенность удаления заключается в том, что столбцы, ха-рактеризующие критерий Харрингтона, должны удалятся в последнюю очередь и в МПЭ необходимо оставить набор столбцов хотя бы одного отклика. Поэтому массивы объектов для формирования векто-ра данных должны иметь на шесть столбцов меньше. Кроме того, в связи с тем, что порядок следования столбцов в модели данных и столбцов различен, необходимо сопоставить имена столбцов в модели столбцов с их номерами в модели данных. Код представлен ниже.

if(arPlanCreate.jt.getColumnCount()==18 ){
col=0;
// Инициализация массива объектов с учетом удаления шести столбцов
Object [] colNamD =new Object [tcm.getColumnCount()-6];
Object [][]    rowDatD = new Object [dtm.getRowCount()][tcm.getColumnCount()-6];
// Определение индекса отклика
int c = arPlanCreate.jt.getSelectedColumn() ;
tc = (TableColumn)tcm.getColumn(c);
nam =tc.getHeaderValue().toString();
if(nam.indexOf(«Y»)>-1){
for(int i = 0; i<nam.length(); i++){
if(‘Y’==(nam.charAt(i))){
nam = nam.substring(i);
break;
}
}
// Выявление столбцов с соответствующим индексом и «желательностью»
for (int i = 0;i<tcm.getColumnCount();i++){
tc=tcm.getColumn(i);
if (((tc.getHeaderValue().toString()).indexOf(nam)==(-1))&&
((tc.getHeaderValue().toString()).indexOf(«Жел»)==(-1))){
//сопоставление имени столбца в модели столбцов с именем в модели данных и формирование
//новых массивов для модели данных
for(int k =0; k < dtm.getColumnCount();k++){
if((tc.getHeaderValue().toString()) == dtm.getColumnName(k)){
for (int j = 0; j < dtm.getRowCount();j++){
colNamD[col] = dtm.getColumnName(k);
rowDatD[j][col]=dtm.getValueAt(j,k);
}
col++;
}
}
}
}
}
// переопределение вектора данных для модели данных таблицы
dtm.setDataVector(rowDatD,colNamD);
arPlanCreate.revalidate();
arPlanCreate.repaint();
}

Аналогичным образом происходит удаление одного отклика. Разница заключается в размере мас-сива для модели данных, и в том, что после удаления необходимо методом setChangeColumn(); перемес-тить в модели столбцов критерий желательности в самый конец.

int c = arPlanCreate.jt.getSelectedColumn() ;
Object [] colNam =new Object [tcm.getColumnCount()-4];
Object [][]    rowDat = new Object [dtm.getRowCount()][tcm.getColumnCount()-4];
TableColumnModel tcm = arPlanCreate.jt.getColumnModel();
tc = (TableColumn)tcm.getColumn(c);
nam =tc.getHeaderValue().toString();
if(nam.indexOf(«Y»)>-1){
for(int i = 0; i<nam.length(); i++){
if(‘Y’==(nam.charAt(i))){
nam = nam.substring(i);
break;
}
}
col= 0;
for(int i=0; i < tcm.getColumnCount();i++){
tc = tcm.getColumn(i);
if((tc.getHeaderValue().toString()).indexOf(nam)==(-1)){
for(int k =0; k < dtm.getColumnCount();k++){
if((tc.getHeaderValue().toString()) == dtm.getColumnName(k)){
for (int j = 0; j < dtm.getRowCount();j++){
colNam[col] = dtm.getColumnName(k);
rowDat[j][col]=dtm.getValueAt(j,k);
}
col++;
}
}
}
}
dtm.setDataVector(rowDat,colNam);
setChangeColumn();


Рисунок 2 МПЭ — после манипуляций со столбцами

Выводы

Все манипуляции со столбцами, имеются в виду, вопросы, связанные с их удалением и пе-ремещением необходимо решать, используя модель данных конкретной таблицы. Так как в противном случае, может возникнуть несогласованность данных, связанная с разным по-рядком следования столбцов в модели столбцов и модели данных.
Для изменения отображения столбцов на экране (удаления и перемещения) удобнее всего пользоваться моделью столбцов таблицы объект TableColumnModel. Но в этом случае не коим образом нельзя манипулировать данными самой таблицы. Так как в этом случае, даже если применить метод объекта TableColumnModel — removeColumn(), столбец не удаляется из модели данных, а просто не выводится на экран.

Источник: http://www.javaportal.ru/java/articles/dataJTable.html
Автор: ЖМАЙЛОВ Борис Борисович (р.1971)

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты