Estoy desarrollando un ComboBox (más por contexto que por significado real), y me gustaría saber si el operador "o" existe en los genéricos de Java. Por ahora, la declaración se ve así:
public class SComboBox<T extends ComboBoxItem> extends JPanel { Donde ComboBoxItem es una interfaz que creé para elementos que se pueden usar en ComboBox. Sin embargo, también me gustaría aceptar String como tipo, lo que parece una tarea difícil ya que:
String es una final class por lo que no hay forma de que alguien pueda extenderla.<T extends A & B> ), imaginé que tendría sentido tener el "o" (|) también.Mi pregunta es esencialmente el punto 2. ¿Puedo, en términos genéricos, especificar una clase que quiero aceptar y/o usar algo como "|"? Si no es así, ¿hay alguna solución o debo descartar la idea de usar genéricos?
No existe el operador "o" para los genéricos, y por una sencilla razón.
La idea de indicar el tipo al principio es permitirle usar métodos de ese tipo en su implementación de la clase.
Cuando usa el operador "y" ( extends A & B ), sabe que cualquier objeto que se le pase, puede acceder a cualquiera de los métodos de la clase A , así como a cualquiera de los métodos de la clase B
Pero, ¿qué pasaría si fuera un "o"? Luego, se le pasa un objeto que puede ser un ComboBoxItem que le permite usar los métodos de ComboBoxItem , o es solo una cadena, lo que significa que no puede usar ninguno de esos métodos. En el momento de la compilación, no sabe qué objeto se le pasa, por lo que no tiene sentido dar el tipo.
El "O" no es útil. Si no está utilizando ningún método del objeto, es mejor que no use extends en absoluto.
La verdadera pregunta aquí es qué está tratando de hacer, que se puede aplicar tanto a las cadenas como a los elementos del cuadro combinado, pero no a nada más. Huele a problema de diseño.
En resumen, esto no es posible. Una clase no puede heredar de una de dos interfaces, ya que sería imposible determinar qué clase se implementa realmente.
Podría implementar un contenedor de cadenas, como mencionó JayC667, y hacer que implemente su interfaz ComboBoxItem. Supongo que necesita algunas funciones especiales introducidas por ComboBoxItem de todos modos.
algún ejemplo:
interface ComboBoxItem{ String getDisplayText(); default Color getBgColor(){ return Color.WHITE; } default Color getFgColor(){ return Color.BLACK; } default ImageIcon getIcon(){ return null; } default boolean useIcon(){ return false; } }Y con una implementación simple que solo toma la entrada de String.
public class StringCbItem implements ComboBoxItem { private final String text; StringCbItem (String text){ this.text = text; } @Override String getDisplayText(){ return text; } }Para el ComboBox, probablemente usaría el JComboBox predeterminado. Puede anular su comportamiento de visualización y representación pasando una implementación personalizada de ListCellRenderer.
public class MyRenderer extends JLabel implements ListCellRenderer<ComboBoxItem> { public MyRenderer () { setOpaque(true); } public Component getListCellRendererComponent(JList<?> list, ComboBoxItem value, int index, boolean isSelected, boolean cellHasFocus) { setText(value.getDisplayText()); setBackground(value.getBgColor()); setForeground(value.getFgColor()); if(value.useIcon()){ setIcon(value.getIcon()); } return this; } } ¡Este es solo un ejemplo de cómo hacerlo y solo pretende ser un punto de partida!
Puedes leer más sobre esto aquí:
Cómo usar cuadros combinados
Interfaz ListCellRenderer