2009-06-24 4 views
15

En ce moment je développe un cadre de liaison basé sur l'annotation pour Java Swing qui utilise JGoodies Binding sous le capot. Malheureusement, je suis coincé avec une annotation pour une liaison JRadioButton. Ce que je veux faire est de spécifier un nom de propriété d'un modèle qui contient une valeur spéciale (enum). Le bouton radio doit être sélectionné si cette propriété a une valeur spécifique. Maintenant, je veux spécifier la valeur dans l'annotation comme ceci:Existe-t-il un moyen de déclarer un attribut d'annotation pour * any * enum?

@RadioButtonBinding(property = "selectedItem", selectedValue = MyEnum.FIRST) 
JRadioButton firstButton 

@RadioButtonBinding(property = "selectedItem", selectedValue = MyEnum.SECOND) 
JRadioButton secondButton 

Cependant, je ne sais pas comment déclarer l'annotation pour permettre au-dessus et toute autre ENUM aussi. Ma première supposition était ceci, mais j'ai appris que les attributs d'annotation ne peuvent pas être génériques:

@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface RadioButtonBinding { 

    /** The model-property to which the selected value is bound */ 
    String property(); 

    // Idea 1: Specifying the enum class and the enum constant as String - works but is not typesafe 

    Class<? extends Enum<?>> enumClass(); 

    String enumConstantName(); 

    // Idea 2: Directly specifying the enum constant - gives a compile-time error 

    <T extends Enum<T>> T enumValue(); 

} 

Des idées pour résoudre ce problème?

+0

L'annotation RadioButtonBinding répertoriée ici comprend deux idées: La première consiste à spécifier la classe Enum et la constante String à utiliser. Mais ce n'est pas sûr, bien sûr, et peut conduire à RuntimeExceptions. La seconde consiste à spécifier directement la valeur d'une énumération, mais cela ne semble pas fonctionner. –

+0

btw J'ai fait beaucoup de ce genre de choses avec JGoodies, l'un des moments les plus misérables que j'ai eu en Java. Le plus gros problème est qu'il a une classe "base" que la plupart de ses autres classes étendent et donc ses méthodes ont la signature comme méthode (base, base, base), où la classe "base" passée doit être une instance spécifique mais le La signature ne vous donne aucune indication quant à la classe spécifique dont elle doit être une instance. La partie reliures était une bonne idée mais il ne l'a pas bien supportée à l'époque (il y a des années) et elle était inachevée et seulement documentée en allemand. –

Répondre

3

Cela ne va pas fonctionner comme vous le souhaitez. Comme vous l'avez découvert, vous ne pouvez utiliser que des types de retour très simples dans les annotations. De plus, essayer de contourner ces restrictions en faisant des choses comme abuser de la chaîne ne fonctionnera pas parce que vous devez utiliser une expression constante pour initialiser les valeurs de votre annotation.

Je pense que le plus proche que vous allez obtenir est d'initialiser avec une chaîne, puis utiliser le code pour comparer avec le nom de l'ENUM(). Mais il va de votre sécurité type ...

1

Si votre énumérations peut mettre en œuvre toute la même interface, vous trouverez peut-être utile à cette question « Coding tip - intersection types and java enums »

+0

Malheureusement non, mais merci pour le pourboire de toute façon. –

+0

Comment exactement utiliseriez-vous cette interface commune dans un attribut d'annotation? ' & MyInterface> T enumValue();' ne fonctionne pas mieux que sans l'interface. – Imre

0

J'ai essayé de résoudre ce même problème exact, et pour autant que Je sais, ça ne peut pas être fait. C'est un vrai bummer. Dans mon cas, je voulais spécifier l'annotation @Version, où n'importe quelle énumération peut être utilisée, et les valeurs enum peuvent être comparées par ordinal (pour trouver l'ordre des versions). On dirait que j'ai besoin de faire ce que font d'autres frameworks (comme Guice je pense) et d'utiliser des doubles à la place; peu moche, mais fonctionne bien pour> = et < = contrôles.

Questions connexes