Moin,
ich versuche folgendes Problem zu lösen:
Es gibt mehrere Klassen die von einer anderen abgeleitet sind. Zu jeder Klasse gibt es eine entsprechende Gegenstückklasse (wenn man so will). Und ich möchte jetzt einfach eine Instanz davon erstellen, anhand der Gegenstückklasse.
Konkret:
Es gibt mehrere Klassen die alle (mehr oder weniger tief) von Field abgeleitet sind. Die möchte ich aber nicht bearbeiten. Stattdessen habe ich einen FieldDrawer. Davon leiten sich verschiedene andere Klassen ab, die anhand eines Fields jetzt was zeichnen.
So sieht die Hauptklasse aus:
Davon abgeleitet gibt es (wie man an der Map sieht):
Jetzt kommt es aber zu einem Fehler, wenn ich folgendes mache:
Anscheinend ignoriert er, dass ich eine Instanz vom Typ Jail übergebe. Ändere ich den Typ im Konstruktor zu „Field“ geht es wunderbar, aber dann möchte ich eigentlich verhindern. Geht das oder muss ich den Typ ändern?
MfG
Fabian
ich versuche folgendes Problem zu lösen:
Es gibt mehrere Klassen die von einer anderen abgeleitet sind. Zu jeder Klasse gibt es eine entsprechende Gegenstückklasse (wenn man so will). Und ich möchte jetzt einfach eine Instanz davon erstellen, anhand der Gegenstückklasse.
Konkret:
Es gibt mehrere Klassen die alle (mehr oder weniger tief) von Field abgeleitet sind. Die möchte ich aber nicht bearbeiten. Stattdessen habe ich einen FieldDrawer. Davon leiten sich verschiedene andere Klassen ab, die anhand eines Fields jetzt was zeichnen.
So sieht die Hauptklasse aus:
Java:
package org.ojim.client.gui.GameField.fielddrawer;
import java.awt.Graphics;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.ojim.logic.state.fields.Field;
import org.ojim.logic.state.fields.GoField;
import org.ojim.logic.state.fields.Jail;
/**
* A abstract drawer to draw a field. For every field class at least one drawer
* has to exists.
*
* Any new drawer has to be set in the internal drawermap. Either by register
* himself or by adding this class in the static block.
*
* Because this is an abstract class it is not possible to create an instance of
* this class. Therefore a {@link #getDrawer(Field)} exists, which returns a
* drawer for a given field-class.
*
* @author Fabian Neundorf.
*/
public abstract class FieldDrawer {
/** Internal map to store which drawer belongs to which fieldclass. */
private static final Map<Class<? extends Field>, Class<? extends FieldDrawer>> drawerMap = new HashMap<Class<? extends Field>, Class<? extends FieldDrawer>>();
/*
* Add here all drawers to the internal map! Or call somewhere in the
* subclass the static method register. This has to be done BEFORE the first
* need of the class.
*/
static {
drawerMap.put(GoField.class, GoFieldDrawer.class);
drawerMap.put(Jail.class, JailDrawer.class);
}
protected Field field;
public FieldDrawer(Field field) {
this.field = field;
}
public abstract void drawTo(Graphics g);
protected static void register(Class<? extends Field> fieldClass,
Class<? extends FieldDrawer> drawerClass) {
drawerMap.put(fieldClass, drawerClass);
}
/**
* Returns the drawer to the given field and sets the field property of this
* new drawer to the given field.
*
* @param field
* The field.
* @return The new drawer.
* @throws InstantiationException
* if this Class represents an abstract class, an interface, an
* array class, a primitive type, or void; or if the class has
* no nullary constructor; or if the instantiation fails for
* some other reason.
* @throws IllegalAccessException
* if the class or its nullary constructor is not accessible.
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws SecurityException
* @throws IllegalArgumentException
*/
public static FieldDrawer getDrawer(Field field)
throws InstantiationException, IllegalAccessException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException {
Class<? extends FieldDrawer> drawer = drawerMap.get(field.getClass());
if (drawer == null) {
throw new IllegalArgumentException("The given field has no drawer.");
}
FieldDrawer newDrawer = drawer.getConstructor(Field.class).newInstance(field);
// FieldDrawer newDrawer = drawer.newInstance();
// newDrawer.setField(field);
return newDrawer;
}
}
Davon abgeleitet gibt es (wie man an der Map sieht):
Java:
package org.ojim.client.gui.GameField.fielddrawer;
import java.awt.Graphics;
import org.ojim.logic.state.fields.Jail;
public class JailDrawer extends FieldDrawer {
public JailDrawer(Jail field) {
super(field);
}
@Override
public void drawTo(Graphics g) {
// TODO Auto-generated method stub
}
}
Jetzt kommt es aber zu einem Fehler, wenn ich folgendes mache:
Java:
FieldDrawer d = FieldDrawer.getDrawer(new Jail());
Code:
java.lang.NoSuchMethodException: org.ojim.client.gui.GameField.fielddrawer.JailDrawer.<init>(org.ojim.logic.state.fields.Field)
at java.lang.Class.getConstructor0(Class.java:2723)
at java.lang.Class.getConstructor(Class.java:1674)
at org.ojim.client.gui.GameField.fielddrawer.FieldDrawer.getDrawer(FieldDrawer.java:107)
at org.ojim.Test.main(Test.java:49)
MfG
Fabian