2010-05-24 3 views
3

Я работаю над симуляцией роботов в Java (приложение Swing). У меня есть абстрактный класс «Робот», из которого производятся разные типы роботов, например.Java загрузка пользовательских классов во время выполнения

public class StupidRobot extends Robot { 
    int m_stupidness; 
    int m_insanityLevel; 
    ... 
} 

public class AngryRobot extends Robot { 
    float m_aggression; 
    ... 
} 

Как вы можете видеть, каждый робот подкласс имеет другой набор параметров.

Что я хотел бы сделать, так это управлять настройкой моделирования в исходном интерфейсе. Выберите количество и тип роботов, укажите имя, запишите параметры и т. Д.

Это одно из тех случаев, когда я был программистом-динозавром и новым для Java, интересно, есть ли какие-то вещи более высокого уровня/думать, что может помочь мне здесь. Так вот что я получил:

(1) Интерфейс пользователя

скроллинга списка типов роботов с левой стороны. "Добавить >>" и "< < Удалить" кнопки посередине. Список прокрученных по умолчанию списков роботов справа. Кнопка «Установить параметры» внизу. (Итак, если вы хотите AngryRobot, вы должны выбрать AngryRobot в левом списке, нажмите «Добавить >>» и «AngryRobot1» появится справа.)

При выборе робота справа нажмите Кнопка «Установить параметры ...», которая вызовет еще одно диалоговое окно модели, в котором вы заполните параметры. Различный диалог, вызываемый для каждого типа .

(2) структуры данных реализация

В качестве конечного продукта я думаю, что HashMap будет наиболее удобно. Ключами будут типы роботов, и сопутствующий объект будет всеми параметрами. Инициализатор может просто извлекать каждый элемент один и время и создавать экземпляр. Вот то, что структуры данных будет выглядеть следующим образом:

enum ROBOT_TYPE {STUPID, ANGRY, etc} 

public class RobotInitializer { 
    public ROBOT_TYPE m_type; 
    public string m_name; 
    public int[] m_int_params; 
    public float[] m_float_params; 
    etc. 

конструктор инициализаторе был бы создать соответствующие массивы параметров длины в зависимости от типа:

public RobotInitializer(ROBOT_TYPE type, int[] int_array, float[] float_array, etc){ 
    switch (type){ 
     case STUPID: 
      m_int_params = new int[STUPID_INT_PARAM_LENGTH]; 
      System.arraycopy(int_array,0,m_int_params,0,STUPID_INT_PARAM_LENGTH); 

     etc. 

После того, как все RobotInitializers инстанцируются, они добавляются к HashMap.

Итерируя через HashMap, инициализатор моделирования берет элементы из Hashmap и создает экземпляры соответствующих роботов.

Разве это разумно? Если нет, то как его можно улучшить?

Благодаря

ответ

1

Как уже отмечалось, вы можете сделать робот реализацией RobotInterface. Затем:

Class aRobotClass = Class.forName("robotClassName"); //or similar 
Class[] aRobotClassImplements = aRobotClass.getIterfaces(); 
// Then ensure that "RobotInterface" exists in the aRobotClassImplements array. 

RobotInterface должен определять геттеры и сеттеры для свойств робота.

Я предполагаю, что у eash-робота может быть целый ряд различных свойств. Можно динамически изучить экземпляр Robot и создать соответствующие кнопки/контроллеры. Например:

Field[] robotFields = aRobotClass.getFields(); 

for (Field field : robotFields) { 
    JButton jbutton = new JButton(field.getName()); 
    //assuming this class implements ActionListener 
    jbutton.addActionListener(this); 
    // Then assume we have a private class representing a button) 
    this.hashMapOrVectorOfButtons.add(new PrivateButton(field)); 
    jpanel.add(jbutton); 
    // etc etc 
} 

Позже в actionPerformed, петля над HashMap или вектор зарегистрированных кнопок. (Field.getName(). (Равно actionEvent.getActionCommand())). Затем манипулируйте соответствующим полем в своем экземпляре Robot.

3

Вы можете использовать отражение для загрузки типов динамически во время выполнения. См. Class.forName, чтобы узнать, как вы можете получить Class, учитывая его полное имя. Затем вы можете использовать метод isAssignableFrom для проверки того, что класс является подклассом Robot. Вы можете определить некоторые методы шаблонов в Robot, чтобы подклассы определяли конкретное поведение (например, какие свойства должны быть инициализированы). После определения класса вы можете использовать метод newInstance() для создания экземпляров Robot (класс должен иметь конструктор по умолчанию, иначе вы должны использовать метод getConstructors() и использовать тот, который вы хотите).

Я знаю, что существует другой способ загрузки определений классов, учитывая полный путь к файлу класса, но не могу вспомнить, как сейчас.

1

Вы также можете использовать RMIClassLoader, хотя я бы рекомендовал ответ Fede, если вы можете использовать его таким образом.

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