Stato di condivisione tra JButtons
Domanda
Voglio creare due o più JButton
s che condividere lo stato, cioèquando il pulsante del mouse viene premuto su entrambi i JButton
, entrambi sono reso depresso (aka "armato"), o se sono caselle di controllo, entrambi sono registrati/non contemporaneamente etc.
Per l'utente, deve apparire come se entrambi i pulsanti sono stati i stesso pulsante, appare in più di un posto nella gerarchia (in realtà Altalena non consentono questo.)
Io posso arrivare a metà strada attraverso la creazione di un unico ButtonModel
e l'assegnazione dello stesso modello per entrambi i pulsanti.Questo consente di sincronizzare le loro armate/controllato/selezionato uniti, etc.
Tuttavia, un effetto che è non condivisa tra i pulsanti in questo modo è la messa a fuoco clic su un pulsante che dà il pulsante di messa a fuoco (indicato da un rettangolo all'interno del pulsante) e la rimuove dall'altro pulsante.Vorrei rendere entrambi i tasti come se fossero concentrati ogni volta che sia pulsante davvero ha la messa a fuoco.
C'è un modo pulito per fare questo?
Idealmente mi piacerebbe essere indipendente dalla scelta di look-and-feel.
Edit: Ho scoperto un altro problema con la condivisione di un ButtonModel
.Quando uno dei pulsanti perde la messa a fuoco, imposta il armed
e pressed
le proprietà del modello di false
.Questo accade dopo gestione mousePressed
, così se si premere il secondo pulsante quando il primo pulsante è attivo, esso non entra in stato premuto fino a quando si preme una seconda volta.
Soluzione
Hai fatto davvero una buona mossa utilizzando la stessa ButtonModel per i due pulsanti.
Ora il tuo problema per quanto riguarda la messa a fuoco.La risposta è No.Non c'è L&F
agnostico modo.È necessario sostituire BasicButtonUI
(o qualunque sia il ButtonUI
si utilizza) e ignorare il focus disegno logica.
Altri suggerimenti
Ecco cosa ho fatto:
- Estendere
JButton
con una nuova classeSharedFocusButton
SharedFocusButton
sostituzionihasFocus
,getModel
epaintBorder
.- Quando
JButton.paintBorder(Graphics)
oButtonUI.update(Component, Graphics)
è in esecuzione, modificare temporaneamente il comportamento dihasFocus
in modo che restituiscatrue
se un qualsiasi pulsante del gruppo, ha la messa a fuoco.Inoltre la facoltà di modificare il comportamento digetModel
per restituire un proxyButtonModel
(altre volte si ritorna condivisaButtonModel
) - Il proxy
ButtonModel
si comporta come predefinito e condivisoButtonModel
, di , salvo che si rifiuta di cambiare ilarmed
opressed
proprietà di valorefalse
mentre la gestione di unfocusLost
evento. - Maniglia
focusGained
efocusLost
, costringendo tutti i pulsanti del gruppo per ridisegnare stessi (questo non avverrà automaticamente, perché ogni pulsante ha una sua interfaccia utente gestione di eventi di attivazione.)
Altre problematiche:
Attenzione attraversamento, probabilmente, dovrebbe essere modificato in modo che il Scheda chiave mai i trasferimenti di messa a fuoco da un pulsante all'altro dello stesso gruppo.
Sto assumendo che tu hai già il testo, ascoltatori e come risolto.
Andando a BasicButtonUI del metodo paint, possiamo vedere che in realtà controlla se il pulsante è attivo, prima di fare certe pittura.Quindi a meno che non si possono avere due concentrati i componenti simultaneamente, l'unico modo che posso pensare è quello di utilizzare il pulsante di altri UI a dipingere.
Entrambi i pulsanti devono essere un FocusButton, e bisogno di chiamare setButton su ogni altro.Io non ho preso la briga di aggiungere qualsiasi null controllo, tra le altre cose.
public class FocusButton extends JButton {
private JButton btn;
public FocusButton() {
addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
// Other button seems to repaint when focus is gained anyway
}
public void focusLost(FocusEvent e) {
btn.repaint();
}
});
}
public void setButton(JButton btn) {
this.btn = btn;
}
public void paint(Graphics g) {
if (!btn.hasFocus()) {
super.paint(g);
} else {
btn.paint(g);
}
}
}
EDIT: Questo non funziona troppo bene, se i pulsanti non sono della stessa dimensione, e, ovviamente, non funziona affatto se si suppone di avere diversi testo.