style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

JComboBox decidir cambio de elemento.

Hola javamexico.org

Me encuentro trabajando sobre un JComboBox que tiene la siguiente información:::

--------------------
-seleccione-
opcion1
opcion2
opcion3
opcion4
------------------

donde -seleccione- está en la lista de opciones del JComboBox

Tal vez les suene extraño lo que vengo a contar pero quiero configurarlo de la siguiente manera:

Cuando carga la interfaz está seleccionada la opción "-seleccione-", luego se selecciona otra opción "opcionX". Si se selecciona ahora la opción "-Seleccione-" debe salir un mensaje diciendo que eso no está permitido y dejar seleccionada la OpcionX anterior.

Lo malo que me pasa es que el análisis de si se escoge "-seleccione-" viniendo de un origen -opcionX- tengo que realizarlo en el ItemListener... ... allí ejecuto un JOptionPane.showMessageDialog(...) para indicar que eso es indebido y al intentar de setear la OpcionX anterior con::: objetoJComboBox.setSelectedItem( objetoOpcionX ) NO me funciona.
SIMPLEMENTE igual si o si se selecciona la opción "-seleccione-" aunque le halla indicado otra con el setSelectedIndex()

--- --- ---
Tengo que confesar que encontré una solución pero me parece poco elegante, y esa consiste de:::

Crear un nuevo objeto JComboBox con las mismas opciones, seleccionar el índice adecuado, añadirle el mismo ItemListener del JComboBox original y añadir el nuevo objeto a la interfaz. Así funciona pero eso me obliga a consultar de nuevo en la Base de Datos por las opciones además de eliminar y añadir elementos al JFrame.
--- ---

¿Como podria lograr mi objetivo de una mejor forma?

Agradezco recomendación y ayuda.

***********************************************************

Posdata:::: para ser mas explicito dejo parte del código, al final explico cual es la idea de el::::

public void setEventosMarcasCB()
        {
                interfaz1.getMarcasCB().addItemListener(
                        new ItemListener()
                        {
                                public void itemStateChanged( ItemEvent evento )
                                {
                                        if ( evento.getStateChange() == ItemEvent.DESELECTED )
                                        {
                                                marcaSeleccionada = (String) interfaz1.getMarcasCB().getSelectedItem();
                                               
                                                //JOptionPane.showMessageDialog( null, "evento.getitem=" + evento.getItem() + "marcaSelec=" + marcaSeleccionada );
                                               
                                                if( evento.getItem().toString().equals("-Seleccion-") )
                                                {
                                                       
                                                        interfaz1.getTiposCB().setEnabled( true );
                                                        interfaz1.setTallas( modelo.getTallas( marcaSeleccionada ) );
                                                }
                                                else if( !marcaSeleccionada.equals( "-Seleccion-") )
                                                {
                                                        int opc = JOptionPane.showConfirmDialog( interfaz1, "¿Realmente desea cambiar de marca?\nAntes: " +
                                                        evento.getItem() + "\nNueva Marca: " + marcaSeleccionada, "Cambio de marca",
                                                        JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE );
                                                       
                                                        if( opc == JOptionPane.YES_OPTION )
                                                        {
                                                                interfaz1.setTallas( modelo.getTallas( marcaSeleccionada ) );
                                                                interfaz1.getTiposCB().setSelectedIndex( 0 );
                                                               
                                                                interfaz1.getReferenciaTF().setEnabled( false );
                                                                interfaz1.getDescripcionTA().setEnabled( false );
                                                                interfaz1.getColorTF().setEnabled( false );
                                                                interfaz1.getPrecioBrutoTF().setEnabled( false );
                                                                interfaz1.getPrecioVentaTF().setEnabled( false );
                                                               
                                                        }
                                                        else
                                                        {
                                                                JComboBox combito = new JComboBox( modelo.getMarcas() );
                                                                combito.setSelectedItem( evento.getItem() );
                                                               
                                                                interfaz1.remove( interfaz1.getMarcasCB() );
                                                                interfaz1.add( combito, 1 );
                                                                interfaz1.validate();
                                                                interfaz1.setMarcasCB( combito );
                                                                setEventosMarcasCB();
                                                        }
                                                }
                                                else
                                                {
                                                        JOptionPane.showMessageDialog(null, "getItem: " + evento.getItem() + " marcaSelec: " + marcaSeleccionada );
                                                       
                                                       
                                                        interfaz1.getMarcasCB().setSelectedItem( evento.getItem() );
                                                        interfaz1.getMarcasCB().setVisible( false);
                                                        interfaz1.getMarcasCB().validate();
                                                        interfaz1.getMarcasCB().setVisible( true);
                                                        interfaz1.setVisible( false );
                                                        interfaz1.validate();
                                                        interfaz1.setVisible( true );
               
                                                       
                                                        interfaz1.getTiposCB().setSelectedIndex( 0 );
                                                        interfaz1.getTiposCB().setEnabled( false );
                                                       
                                                        interfaz1.getTallasCB().setSelectedIndex( 0 );
                                                        interfaz1.getTallasCB().setEnabled( false );
                                                       
                                                       
                                                }
                                               
                                               
                                               
                                        }
                                       
                                       
                                }
                        }
                       
                );
        }

**************************************************

Cuando no se cumple la condición

"if( opc == JOptionPane.YES_OPTION )"

se pasa al respectivo ELSE donde hago la técnica poco elegante que mencioné arriba... verán como hago un llamado recursivo al mismo método para asignarle su método de escucha.

Aunque no es el mismo caso que menciono al principio es la misma idea que será aplicable al otro bloque de código que explico a continuación ----------------->

---------------> Cuando no se cumple la instrucción "else if( !marcaSeleccionada.equals( "-Seleccion-") )" nos vamos a su ELSE

donde ejemplifico lo que no me funciona

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de Nopalin

Usando ActionListener

yo utilize un action listener, pero igual funciona y es mas simple, lo único es que se debe llevar una variable externa para saber cual es el ultimo elemento seleccionado para poder regresar a el cuando se requiera, aquí el codigo, espero y sea lo que pides:

package pm.singles;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class ComboSeleccion extends JFrame{

        JComboBox combo;
        int ultimoIndiceSeleccionado = 0;
       
        public ComboSeleccion(){
                setTitle("Prueba de combo");
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
               
                combo = new JComboBox();
                combo.addItem("-Seleccion-");
                combo.addItem("Spiderman");
                combo.addItem("Batman");
                combo.addItem("Ironman");
                combo.addItem("Linterna Verde");
                combo.addItem("Kaliman");
                combo.setSelectedIndex(ultimoIndiceSeleccionado);
               
                JPanel panel = new JPanel();
                panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
                panel.add(new JLabel("Seleccione un elemento"));
                panel.add(Box.createHorizontalStrut(10));
                panel.add(combo);
               
                combo.addActionListener(new ActionListener(){
                        @Override public void actionPerformed(ActionEvent e) {
                                elementoCambiado();
                        }
                });
               
               
                getContentPane().add(panel);
                pack();
                setVisible(true);
        }
       
        public void elementoCambiado() {
                int index = combo.getSelectedIndex();
                if(ultimoIndiceSeleccionado != 0 && index == 0){
                        int opc = JOptionPane.showConfirmDialog(this, "¿Realmente desea cambiar de marca?",
                                "Cambio de marca", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE );
                       
                        if(opc == JOptionPane.NO_OPTION){
                                combo.setSelectedIndex(ultimoIndiceSeleccionado);
                        } else{
                                ultimoIndiceSeleccionado = index;
                        }
                } else{
                        ultimoIndiceSeleccionado = index;
                }
        }
       
        public static void main(String[] args){
                try{
                        new ComboSeleccion();
                } catch(Exception ex){
                        ex.printStackTrace();
                }
        }
}

Saludos

Imagen de ezamudio

delay

Otra opción es que hagas el setSelectedIndex() más tarde, después de que termine de ejecutarse tu método. Puede ser con un Timer que ejecute la tarea una sola vez, unos 50ms después...

Imagen de samz550a

genial, me parece muy bien,

genial, me parece muy bien, al parecer estaba pasando por alto otros diferentes tipos de eventos al que estaba manejando.

Muchas gracias Nopalin, añadiré tu solución a mi código.

Un gran saludo.

Imagen de samz550a

Muchas gracias Ezamudio por

Muchas gracias Ezamudio por tu recomendación y ayuda. Había pensado en esa opción con el Timer pero no me decanté por ella.

Realmente desearía que funcionara tan solo con la lógica que _falla_ pero al parecer al implementarla dentro del mismo manejo del evento no es nada exitoso... supongo que el mecanismo de eventos se asegura que si o si quede seleccionado el elemento clickeado así sea que en el código de manejo de eventos se indique otra cosa... ... es como si fuera necio o reacio a mis ordenes, llega a ser un poquitín frustrante.

Ante el caso me pregunto ¿es una regla del lenguaje que desde el código de manejo del evento ItemEvent _No_ se pueda alterar que el elemento seleccionado sea otro distinto al clickeado?

Saludos.

Imagen de ezamudio

no del lenguaje

Eso ya no es una cosa a nivel de lenguaje, es simplemente la manera en que está implementado el manejo de eventos para el JComboBox en Swing. Cuando tienes un ItemListener, le llega el evento del cambio de selección, pero al llamarse tu método, debes tomar en cuenta que tu código corre todavía dentro del evento. Si al cambiar la selección en tu código se generara nuevamente un evento, podría generarse un problema de recursión infinita (tal vez no con tu caso particular pero con muchos otros sí), por lo que seguramente hacen algo para deshabilitar temporalmente el envío de más eventos dentro de ese mismo evento. Y probablemente todavía no se hace realmente el cambio en el combo, sino hasta que termina tu método, de modo que aunque hagas cambios directamente al combo, saliendo de tu método es cuando realmente se cambia la selección.

Imagen de samz550a

correcto :D gracias por la

correcto :D gracias por la aclaración y ayuda. Realmente me sucedió como tu mencionas @chochosmx

Ya por fin pude implementarlo como recomendó nopalin luego de fallarme hartas veces por puro descuido >_< hoy tengo déficit de atención al parecer.

Un gran saludo.

Imagen de samz550a

por cierto

tengo dos JComboBox y en el 2 implementé tu solución del Timer.

Igualmente se puede hacer funcionar pero es un poco engorroso porque hay que tener en cuenta que cuando se da el objetoCombo.setSelectedItem( objetoLista ) dentro del ActionListener del Timer se invoca de nuevo el ItemListener de forma recursiva (como muy bien preveías ).

Solo quería comentar como me había ido con esta otra solución.

Un saludo.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">