Domanda

Voglio creare due o più JButtons 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.

È stato utile?

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 classe SharedFocusButton
  • SharedFocusButton sostituzioni hasFocus, getModel e paintBorder.
  • Quando JButton.paintBorder(Graphics) o ButtonUI.update(Component, Graphics) è in esecuzione, modificare temporaneamente il comportamento di hasFocus in modo che restituisca true se un qualsiasi pulsante del gruppo, ha la messa a fuoco.Inoltre la facoltà di modificare il comportamento di getModel per restituire un proxy ButtonModel (altre volte si ritorna condivisa ButtonModel)
  • Il proxy ButtonModel si comporta come predefinito e condiviso ButtonModel, di , salvo che si rifiuta di cambiare il armed o pressed proprietà di valore false mentre la gestione di un focusLost evento.
  • Maniglia focusGained e focusLost, 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top