2011-01-28 19 views
9

Tengo un JComboBox que necesita ser desactivado en algún momento, pero siento que el estado disabled hace que sea más difícil de leer debido al bajo contraste que tiene.Mejor legibilidad/contraste en un JComboBox desactivado

Sería bueno si solo el botón de la flecha desplegable se mostrara como deshabilitado, mientras se mantiene el renderizador de cuadro como si estuviera habilitado.

real: actual combo deseado: desired result

¿Hay una manera fácil de lograr esto o algo similar?

Gracias!

Respuesta

6

he terminado asomando la BasicComboBoxUI, donde me he encontrado esto:

 if (comboBox.isEnabled()) { 
      c.setForeground(comboBox.getForeground()); 
      c.setBackground(comboBox.getBackground()); 
     } 
     else { 
      c.setForeground(DefaultLookup.getColor(
        comboBox, this, "ComboBox.disabledForeground", null)); 
      c.setBackground(DefaultLookup.getColor(
        comboBox, this, "ComboBox.disabledBackground", null)); 
     } 

Así que he usado como componente procesador de un JLabel con el método setForeground anulado por no hacer nada. Por lo tanto, el color nunca cambia y mantiene el valor de negro predeterminado.

El problema es que este truco es específico de la implementación. Un aspecto determinado & Feel o UI Manager puede hacer otras cosas como pintar con una capa semitransparente para mostrar los elementos desactivados en lugar de cambiar los colores del componente :-(

Tal vez una prueba podría dar una advertencia si el L instalado & F o interfaz de usuario Administrador no llama al método setForeground

6

Aquí hay otra opción que tiene:..

jComboBox1.setRenderer(new DefaultListCellRenderer() { 
     @Override 
     public void paint(Graphics g) { 
      setForeground(Color.BLACK); 
      super.paint(g); 
     } 
    }); 

usted sólo tendrá que añadir este código después de la creación de instancias las cartas siempre se mantendrán negro el. cuadro combinado cuadro se convertirá en ya sea gris o negro si deshabilita o habilita.

se ven así:

enter image description here

+1

Lamentablemente, esto tiene el mismo inconveniente que la otra solución, un administrador de interfaz de usuario que utiliza una técnica de pintura para atenuar el componente todavía daría resultados insatisfactorios. Además, el método de pintura se llamará más veces que 'setForeground', por lo que es mucho más eficiente dejarlo sin modificar y sobrescribir el otro. – fortran

+1

¿No se ve exactamente como el "deseado"? –

+0

¿Dónde dije que no se vería correctamente? El problema es que tiene el mismo defecto que mi solución temporal: depende de la implementación. Un cambio en la forma en que L & F o UI Manager logra el efecto desactivado (ya lo describí de otra manera, hay más) y luego se rompe. – fortran

6

Aquí hay otro truco, due to Michael Grimes, que no debe ser afectada por la particular mirada y sentir. El truco es hacer que el cuadro combinado sea editable; el JTextField que está expuesto ya que el editor admite el método setDisabledTextColor. Y como está deshabilitando el cuadro combinado, ¡no importa que sea editable! El código que estoy usando para ello (traducido del Scala) es la siguiente:

JComboBox cb = ...; 
... 
cb.setEditable(true); 
ComboBoxEditor editor = cb.getEditor() 
JTextField  etf = (JTextField)etf.getEditorComponent() 
etf.setDisabledTextColor(UIManager.getColor("ComboBox.foreground")); 
etf.setBackground(UIManager.getColor("ComboBox.background")); 
// editor.setItem(format(obj)); 
cb.setEnabled(false); 

El elenco está garantizado para tener éxito aquí porque estamos usando un BasicComboBoxEditor, cuyos documentos dicen "El editor se implementa como un JTextField ". La línea comentada se produce porque estoy usando un renderizador personalizado que imprime enteros con texto adicional que los rodea; Llamar al setItem me permite especificar una cadena similar, y es necesaria porque el editor ignora el renderizador personalizado. Si está usando el renderizador predeterminado, entonces no necesita preocuparse por esa línea; por otro lado, si está usando un renderizador más complicado, entonces podría necesitar hacer algo completamente diferente.

A pesar del hecho de que este es un error horrible, funciona, y no parece depender de ninguna característica definida por la implementación.Los dos lugares en los que podría imaginar esta ruptura son (a) si un cuadro combinado editable se ve muy diferente de uno no editable (por ejemplo, mi primer intento no cambió el color de fondo del campo de texto, lo que lo hizo ver mal) , o (b) si BasicComboBoxEditor dejó de devolver un JTextField (lo que parece menos probable). Pero hasta ahora, está sirviendo a mis propósitos.

4

probar este **

UIManager.put("ComboBox.disabledBackground", new Color(212,212,210)); 
UIManager.put("ComboBox.disabledForeground", Color.BLACK); 

**

+1

Eso cambia todos los cuadros combinados, solo quiero cambiar uno. – fortran

+0

+1, exactamente lo que necesito, ¡ya veo! (Quiero comportarme todos los cuadros combinados de forma idéntica) –

+0

¡Gran solución! Es exactamente lo que necesito –

0

El resultado se puede lograr con el siguiente código:

Component editorComponent = comboBox.getEditor().getEditorComponent(); 
    if(editorComponent instanceof JTextComponent){ 
     ((JTextComponent)editorComponent).setDisabledTextColor(Color.black); 
    } 

no he probado con varios & L M, pero podría hacer una diferencia, ya que esto activa un evento PropertyChange ("disabledTextColor"). Por favor, consulte el docs.