2013-08-19 4 views
0

У меня есть несколько объектов (Terminal, Runway, Gate, Airline, работники и т. Д.), Которые мне нужно показать в JTable. Я пытаюсь создать GenericTableModel (использовать с JTable), который будет работать для каждой коллекции. Вещь - некоторые из этих объектов имеют структуры данных, и я не хочу показывать эти структуры. Итак, я получаю имена столбцов, получая первый объект из коллекции и запрашивая его объявленные поля, которые не могут быть назначены из классов AbstractMap или Collection. Кажется, это работает для меня, я получаю только те поля, которые мне нужны. Проблема начинается, когда я пытаюсь показать рабочих. У меня есть абстрактный класс W_Worker с большинством полей для рабочего, и у меня есть разные работники, такие как W_Manager, W_FuelWorker и т. Д. Каждый из подклассов имеет только 1 или 2 поля, и когда я помещаю их в таблица, использующая мой GenericTableModel. Я получаю только поля от конкретного рабочего без полей из W_Worker.Java Generic programming: определение того, расширяет ли класс еще один

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

Я предоставлю код, если этого недостаточно, чтобы понять. Заранее благодарен, Тал

Редактировать: Код добавлен.

public String[] getColumnName(Collection<T> collection){ 
    Field fields[] = null; 
    String fieldsNames[]; 
    ArrayList<String> desiredFields = new ArrayList<>(); 

    for(Object o : collection){ 
     fields = o.getClass().getDeclaredFields(); 
     if (o instanceof W_Worker){ 
      Field[] superFields = o.getClass().getSuperclass().getDeclaredFields(); 
      Field[] result = new Field[superFields.length + fields.length]; 
      System.arraycopy(superFields, 0, result, 0, superFields.length); 
      System.arraycopy(fields, 0, result, superFields.length, fields.length); 
      fields = result; 
     } 
     break; 
    } 
    fieldsNames = new String[fields.length]; 
    for(int i = 0; i<fields.length ;i++){ 
     if (!Collection.class.isAssignableFrom(fields[i].getType()) && !AbstractMap.class.isAssignableFrom(fields[i].getType())){ 
      fieldsNames[i] = fields[i].getName(); 
     } 
    } 
    for(String field : fieldsNames){ 
     if (field != null){ 
      desiredFields.add(field); 
     } 
    } 
    String newFields[] = new String[desiredFields.size()]; 
    return desiredFields.toArray(newFields); 
} 

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

+1

Некоторый код будет полезен с вашей стороны. – anubhava

+0

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

+0

Все ли ваши классы расширяют общий класс?В противном случае, если вы начинаете с одного класса узлов, как вы узнаете, когда достигнете корня вашей иерархии? Если они не принадлежат к общему предку, я не думаю, что вы можете предотвратить hardcoding имена классов там, как вы. –

ответ

0

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

Спасибо за ваши ответы и время.

0

Для любого класса вы можете видеть, что он расширяет и/или реализует, используя Reflection. Затем выполните сравнение с типами разных рабочих классов и вызовите метод, который вам подходит. Полностью обработанный пример находится в тропе: http://docs.oracle.com/javase/tutorial/reflect/class/classModifiers.html

1

Я бы рассмотрел Visitor Pattern для этого. Посетитель знал бы, как обращаться с TableModel.

Несколько как это:

public class TableModelVisitor { 

    private TableModel model; 

    public void visit(Terminal terminal) { 
     terminal.accept(this); 
    } 
    public void visit(Runway runway) { 
     runway.accept(this); 
    } 
    public void visit(Worker worker) { 
     worker.accept(this); 
    } 

    //your methods to treat the model 
} 

Тогда вы можете сделать каждую сделку узел с посетителем и попросить его сделать что-то вроде заполнения модели:

public class Worker { 
    public void accept(TableModelVisitor tableModelVisitor) { 
     //and here you know everything about your worker and its fields 
     //and have access to your visitor table model to configure it. 
     tableModelVistor.addField(this.getMyField1()); 
     tableModelVistor.addField(this.getMyField2()); 
    } 
} 

В конце концов, все, что вам сделать это, чтобы создать TableModelVisitor и попросить его заполнить любую желаемую модель.

TableModelVisitor visitor = new TableModelVisitor(myTableModel); 
visitor.visit(anyOfMyObjects); 
+0

Спасибо, но меня попросили создать модель таблицы общего типа, которая будет работать для всех коллекций, и ваш метод будет работать (если я правильно понял) только для классов, которые я создам методом посещения. – talki

Смежные вопросы