2011-01-28 17 views
9

Ho un JComboBox che deve essere disabilitato a un certo punto, ma mi sento che lo stato disabled rende molto più difficile da leggere perché il basso contrasto che ha.Migliore leggibilità/contrasto in disabile JComboBox

Sarebbe bello se solo il pulsante freccia a discesa fosse visualizzato come disabilitato, mantenendo il renderizzatore di riquadri come se fosse abilitato.

reale: actual combo desiderata: desired result

C'è un modo semplice per ottenere questo o qualcosa di simile?

Grazie!

risposta

6

ho finito per sbirciare il BasicComboBoxUI, dove ho trovato questo:

 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)); 
     } 

Così ho usato come componente di un renderer JLabel con il metodo setForeground sovrascritto di non fare nulla. Pertanto, il colore non viene mai modificato e mantiene il valore del nero predefinito.

Il problema è che questo trucco è specifico per l'implementazione. Un dato Look & Feel o UI Manager potrebbe fare altre cose come la sovrapposizione con un livello semi-trasparente per visualizzare gli elementi disabilitati invece di cambiare i colori del componente :-(

Forse un test potrebbe almeno dare un avvertimento se il L installato & F o UI manager non chiamano il metodo setForeground

6

Ecco un'altra opzione che avete:..

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

avrete solo bisogno di aggiungere questo codice dopo l'istanza le lettere saranno sempre rimanere nero The. il frame della casella combinata diventerà grigio o nero se disabiliti o abiliti.

Sembrano questo:

enter image description here

+1

Purtroppo questo ha lo stesso inconveniente dell'altra soluzione, un gestore dell'interfaccia utente che utilizza una tecnica di paint-over per attenuare il componente darebbe comunque risultati insoddisfacenti. Inoltre, il metodo paint verrà chiamato più volte di "setForeground", quindi è apparentemente più efficiente lasciarlo invariato e sovrascrivere l'altro. – fortran

+1

Non sembra esattamente il "desiderato"? –

+0

Dove ho detto che non sarebbe stato corretto? Il problema è che ha lo stesso difetto della mia soluzione: dipende dall'implementazione. Un cambiamento nel modo in cui L & F o UI Manager raggiunge l'effetto disabilitato (ho già descritto un altro modo, ce ne sono altri) e poi è rotto. – fortran

6

Ecco un altro trucco, due to Michael Grimes, che non dovrebbe essere influenzata dalla particolare aspetto grafico. Il trucco è rendere la casella combinata modificabile; il JTextField esposto come l'editor supporta il metodo setDisabledTextColor. E dal momento che stai disattivando la casella combinata, non importa che sia modificabile! Il codice che sto usando per fare questo (tradotto da Scala) è la seguente:

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); 

Il cast è garantito per avere successo qui perché stiamo usando un BasicComboBoxEditor, i cui documenti dire "L'editor è implementata come un JTextField. " La riga commentata si verifica perché sto utilizzando un renderer personalizzato che stampa interi con testo extra che li circonda; chiamare setItem mi consente di specificare una stringa simile ed è necessario perché l'editor ignora il renderer personalizzato. Se stai usando il renderer predefinito, non devi preoccuparti di quella linea; d'altra parte, se stai usando un renderer più complicato, potresti dover fare qualcos'altro interamente.

Nonostante il fatto che si tratti di un orribile clandestino, lo funziona e non sembra fare affidamento su alcuna funzione definita dall'implementazione.I due punti in cui potrei immaginare questa rottura sono (a), se una casella combinata modificabile sembra molto diversa da una non modificabile (ad esempio, il mio primo tentativo non ha cambiato il colore di sfondo del campo di testo, il che ha fatto sembrare sbagliato) , o (b) se BasicComboBoxEditor ha smesso di restituire un JTextField (che sembra meno probabile). Ma finora, sta servendo i miei scopi.

4

Prova questa **

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

**

+1

Che cambia tutte le caselle combinate, voglio solo cambiarne una. – fortran

+0

+1, esattamente quello di cui ho bisogno, posto! (Voglio comportarmi in modo identico su tutti i combobox) –

+0

Ottima soluzione! È esattamente ciò di cui ho bisogno –

0

Il risultato può essere raggiunto con il seguente codice:

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

non ho la prova con diversi L & F, ma potrebbe fare la differenza, poiché questo fa scattare un evento PropertyChange ("disabledTextColor"). Si prega di consultare il docs.