2012-02-23 18 views
5

Sto utilizzando una JList per contenere i dati della chat per il mio programma di chat.
Utilizza un renderer di elenco personalizzato per eseguire il rendering di un oggetto JPanel personalizzato come tipo di elemento.
Questo JPanel contiene due JLabel (ancorati in alto, per nome e ora) e un JTextArea (ancorato in fondo, per messaggio di chat).Revalidating JList - elementi personalizzati

Ecco come si presenta:

a pic1 http://oi44.tinypic.com/20jiix5.jpg

Tutto grandi opere, ma voglio aggiungere una funzione nascondi/mostra.
Utilizzando un gestore PopupMenu precedentemente programmato, viene visualizzato un popup quando si fa clic con il pulsante destro del mouse su un elemento.

a pic2 http://oi42.tinypic.com/2m5exxt.jpg

Quando si fa clic nascondere (o spettacolo, è un toggle) allora dovrebbe ridurre al minimo l'elemento in questo modo ...

a pic3 http://oi41.tinypic.com/kf3apx.jpg

L'unico problema è ... che doesn Aggiorna la dimensione della cella JList come puoi vedere la grande area vuota in cui un tempo si trovava il testo.
Tuttavia, quando si digita un altro messaggio ...

a pic4 http://oi40.tinypic.com/35jdoo7.jpg

Il JList fissa le dimensioni della cella completando l'operazione di 'nascondere'.
La mia domanda è come si ottiene JList per riconvalidare/ridisegnare/etc a livello di programmazione.
E non credere che non ho provato tutte le soluzioni ovvie ...

public void setHidden(boolean hidden) { 
    // this is in the custom JPanel class 
    System.out.println("Initial: " + this.getPreferredSize()); 

    // TextArea is the JTextArea which we set invisible when we want to hide it. 
    TextArea.setVisible(!hidden); // TextArea is a variable btw 
    this.invalidate(); 
    this.validate(); 
    this.repaint(); 

    System.out.println("After: " + this.getPreferredSize()); 
    container.revalidate(); 
} 

/* 
* This is what the above printlns show when you hide, then show the element. 
* 
* Initial: java.awt.Dimension[width=176,height=38] 
* After: java.awt.Dimension[width=176,height=20] 
* Initial: java.awt.Dimension[width=176,height=20] 
* After: java.awt.Dimension[width=176,height=38] 
*/ 

public void revalidate() { 
    // container.revalidate() ^^^ 
    // list is the list containing the chat elements 
    list.invalidate(); 
    list.validate(); 
    list.repaint(); 
} 

La classe JPanel personalizzato utilizza un GroupLayout per rendere i componenti.
Ragazzi, avete qualche conoscenza su come programmare a livello di programmazione una JList per riconvalidarne le dimensioni?
... oltre ai metodi che ho postato? :)

Soluzione:
Dopo metodo di ricerca dopo che il metodo e la verifica se avrebbero risolvere il mio problema, ho scoperto che l'esecuzione di questo codice dopo un'operazione Mostra/Nascondi causerebbe l'altezza della cella (e larghezza) essere ricalcolati e senza alcun 'sfarfallio' visivo indesiderato di JList.

list.setFixedCellHeight(0); 
list.setFixedCellWidth(0); 
list.setFixedCellHeight(-1); 
list.setFixedCellWidth(-1); 
+0

si prega di imparare le convenzioni di denominazione java e attenersi a loro – kleopatra

+0

Conosco la convenzione di denominazione java, mi piace solo avere le mie variabili di oscillazione maiuscole. Ma non sempre lo seguo ... –

risposta

2

Si tratta di lavoro per JTable con due colonne (Chat e Boolean) nel TableModel e con visibile Chat colonna solo, il trucco è quello di utilizzare per implementare RowFilter in cui si imposta come parametro per la seconda colonna solo String "false" (Object nel JTable con Boolean è possibile filtrante con il valore ritorna nella String "true"/"false")

+0

Il tuo grammatica rende la tua risposta difficilmente comprensibile. In che modo questa JTable corregge il ridimensionamento della cella? E devi ricordare che sto usando un renderer di celle personalizzato per eseguire il rendering di questa JList. Non mostrerebbe quello che fa senza di esso. –

+0

@Bradley Odell per favore leggi il tutorial [JList] (http://docs.oracle.com/javase/tutorial/uiswing/components/list.html) su Model (ci sono dati memorizzati) e View e il suo renderering, non mai don 't use invalidate() – mKorbel

3

Senza vedere alcun codice, posso solo immaginare: la ragione più probabile è che si sta facendo la pelle sotto i piedi della l ist, cioè senza il suo modello che notifica i suoi ascoltatori.Il delegato ui della lista memorizza nella cache la dimensione della cella in profondità, che viene cancellata alla ricezione di ListEvents

+0

Pensi che stia facendo clic con il pulsante destro del mouse e nascondendo l'elemento con il mio cursore fisicamente sotto la JList? Tutto ciò che accade quando "nascondo" l'elemento è il JTextArea (che contiene il messaggio di chat) che viene impostato come invisibile. Quindi, quando viene modificata la visibilità, ho bisogno di JList per ricalcolare la sua dimensione di cella per quell'elemento. –

0

Questo è un difetto molto particolare della classe JList. Mi sono imbattuto personalmente nel problema della pulizia di parte del mio codice in aree non correlate.

Per quello che vale, rimuovere l'elemento dallo ListModel e quindi aggiungerlo di nuovo produrrà le dimensioni appropriate per il componente di rendering associato in JList. E 'uno strano modo per andare su di esso, e sembra causare la lista a comportarsi nello stesso modo come la soluzione accettata (e preferito):

list.setFixedCellHeight(0); 
list.setFixedCellWidth(0); 
list.setFixedCellHeight(-1); 
list.setFixedCellWidth(-1); 

sono incappato in questo problema perché il codice per il mio progetto è stato originariamente scritto per richiamare il metodo removeAllElements() dello ListModel e quindi aggiungere nuovamente tutti gli elementi uno per uno utilizzando addElement(). Tutto funzionava alla perfezione fino a quando ho deciso che avrei dovuto riscrivere il programma in modo tale da lasciare semplicemente il modello da solo ogni volta che venivano richieste all'utente le modifiche alle dimensioni dei componenti visualizzati in JList. In altre parole, non era necessario coinvolgere il modello perché gli elementi non venivano aggiunti o rimossi dall'elenco. Sfortunatamente, dopo aver modificato la dimensione preferita del renderer, nessuna quantità di chiamate al metodo o revalidate() sullo JList causerebbe il corretto layout degli elementi. Nel mio caso, solo il ridimensionamento del componente principale (a JFrame) ha prodotto il comportamento previsto.