GWT - pulsante mutuamente esclusivo ginocchiera
-
20-09-2019 - |
Domanda
Voglio un ibrido di un ToggleButton e RadioButton . Voglio che la parte "mutuamente esclusiva" di RadioButton, e l'aspetto e il comportamento di gui ToggleButton (su e giù per gli stati). Si fa a esiste già?
Soluzione
Ho adattato la soluzione di kirushik e creato un semplice widget "ToggleButtonPanel" che prende un numero arbitrario di ToggleButtons (e possibilmente qualsiasi altro widget che desideri aggiungere) e un pannello di vostra scelta (il default è VerticalPanel) e marche i tasti mutuamente esclusivo.
Cosa c'è di bello di questo è che il pannello stesso spara ClickEvents quando i pulsanti sono cliccato. In questo modo, è possibile aggiungere un singolo clickHandler al ToggleGroupPanel e quindi determinare quale pulsante è stato fatto clic con evento.getSource ()
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class ToggleButtonPanel extends Composite implements HasWidgets, HasClickHandlers{
public ToggleButtonPanel() {
this(new VerticalPanel());
}
public ToggleButtonPanel(Panel panel){
this.panel = panel;
initWidget(panel);
}
@Override
public void add(Widget w) {
if(w instanceof ToggleButton){
ToggleButton button = (ToggleButton) w;
button.addClickHandler(handler);
}
panel.add(w);
}
@Override
public void clear() {
panel.clear();
}
@Override
public Iterator<Widget> iterator() {
return panel.iterator();
}
@Override
public boolean remove(Widget w) {
return panel.remove(w);
}
@Override
public void setWidth(String width) {
panel.setWidth(width);
};
@Override
public void setHeight(String height) {
panel.setHeight(height);
}
private final Panel panel;
private ClickHandler handler = new ClickHandler(){
@Override
public void onClick(ClickEvent event) {
Iterator<Widget> itr = panel.iterator();
while(itr.hasNext()){
Widget w = itr.next();
if(w instanceof ToggleButton){
ToggleButton button = (ToggleButton) w;
button.setDown(false);
if(event.getSource().equals(button)) {
button.setDown(true);
}
}
}
for(ClickHandler h : handlers){
h.onClick(event);
}
}
};
private List<ClickHandler> handlers = new ArrayList<ClickHandler>();
@Override
public HandlerRegistration addClickHandler(final ClickHandler handler) {
handlers.add(handler);
return new HandlerRegistration() {
@Override
public void removeHandler() {
handlers.remove(handler);
}
};
}
}
Altri suggerimenti
Ecco il mio puro-GWT variante:
class ThreeStateMachine extends FlowPanel{
// This is the main part - it will unset all the buttons in parent widget
// and then set only clicked one.
// One mutual handler works faster and is generally better for code reuse
private final ClickHandler toggleToThis = new ClickHandler() {
@Override
public void onClick(ClickEvent clickEvent) {
for(Widget b: ThreeStateMachine.this.getChildren()){
((ToggleButton)b).setDown(false);
}
((ToggleButton)clickEvent.getSource()).setDown(true);
}
};
private ThreeStateMachine() { // Create out widget and populat it with buttons
super();
ToggleButton b = new ToggleButton("one");
b.setDown(true);
b.addClickHandler(toggleToThis);
this.add(b);
b = new ToggleButton("two");
b.addClickHandler(toggleToThis);
this.add(b);
b = new ToggleButton("three");
b.addClickHandler(toggleToThis);
this.add(b);
}
}
Certamente, one'll bisogno di stili CSS per GWT-ToggleButton con varianti (up-in bilico, ecc.)
Ho qualcosa che sia non in una biblioteca di estensione, e non dipende da un pannello come le altre risposte. Definire questa classe che gestisce i pulsanti. Stiamo aggiungendo un nuovo click ascoltatore ai pulsanti, che si aggiunge a qualsiasi gestore di clic è stato collegato nella classe "Content GUI". Non riesco a copiare e incollare questo, quindi speriamo che sia sintatticamente corretta.
public class MutuallyExclusiveToggleButtonCollection {
List<ToggleButton> m_toggleButtons = new ArrayList<ToggleButton>();
public void add(ToggleButton button) {
m_toggleButtons.add(button);
button.addClickListener(new ExclusiveButtonClickHandler());
}
private class ExclusiveButtonClickHandler impelments ClickHandler {
public void onClick(ClickEvent event) {
for(ToggleButton button : m_toggleButtons) {
boolean isSource = event.getSource().equals(button);
button.setIsDown(isSource);
}
}
}
Mi sono imbattuto lo stesso bisogno, ecco un'altra soluzione che elimina il gestore separato e funziona bene in UIBinder con una dichiarazione del tipo:
<my:RadioToggleButton buttonGroup="btnGroup" text="Button 1" />
Ecco la classe estesa:
import java.util.HashMap;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.user.client.ui.ToggleButton;
public class RadioToggleButton extends ToggleButton
{
private static HashMap<String,ButtonGroup> buttonGroups = new HashMap<>();
private ButtonGroup buttonGroup;
public @UiConstructor RadioToggleButton( String buttonGroupName )
{
buttonGroup = buttonGroups.get( buttonGroupName );
if( buttonGroup == null ){
buttonGroups.put( buttonGroupName, buttonGroup = new ButtonGroup() );
}
buttonGroup.addButton( this );
}
@Override
public void setDown( boolean isDown )
{
if( isDown ){
RadioToggleButton btn = buttonGroup.pressedBtn;
if( btn != null ){
btn.setDown( false );
}
buttonGroup.pressedBtn = this;
}
super.setDown( isDown );
}
private class ButtonGroup implements ClickHandler
{
RadioToggleButton pressedBtn = null;
public void addButton( ToggleButton button )
{
button.addClickHandler( this );
}
@Override
public void onClick( ClickEvent event )
{
Object obj = event.getSource();
if( pressedBtn != null ){
pressedBtn.setDown( false );
}
pressedBtn = (RadioToggleButton)obj;
pressedBtn.setDown( true );
}
}
}
"Questo esempio illustra Bottoni Toggle. Quando si fa clic, tali pulsanti alternare il loro stato 'premuto'.
I pulsanti grassetto, corsivo e sottolineato ginocchiera funzionano in modo indipendente rispetto al loro stato di commutazione, mentre l'icona allineamento del testo pulsanti appartengono allo stesso gruppo a ginocchiera e così quando uno di loro è cliccare, il già pressati ritorna Button al suo stato normale. "
Pubblicare un clickHandler aggiuntivo su tutti i ToggleButtons. Ad esempio, ToggleButtons casa, albero, sintesi, particolare.
public class Abc extends Composite implements ClickHandler {
ToggleButton home, tree, summary, detail
public Abc() {
// all your UiBinder initializations... blah, blah....
home.addClickHandler(this);
tree.addClickHandler(this);
summary.addClickHandler(this);
detail.addClickHandler(this);
}
@Override
public void onClick(ClickEvent p_event) {
Object v_source = p_event.getSource();
home.setDown(home==v_source);
tree.setDown(tree==v_source);
summary.setDown(summary==v_source);
detail.setDown(detail==v_source);
}
}
Naturalmente, basta aggiungere tutti gli altri codice standard e registrare ClickHandlers aggiuntivi per ogni ToggleButton.