Pregunta

Quiero un híbrido de un ToggleButton y RadioButton . Quiero que la parte "mutuamente excluyente" de RadioButton, y el aspecto y el comportamiento de GUI ToggleButton (arriba y abajo de los estados). Existe ya uno?

¿Fue útil?

Solución

He adaptado la solución de kirushik y creé un widget simple "ToggleButtonPanel" que tiene un número arbitrario de ToggleButtons (y posiblemente otros widgets que desea agregar) y un panel de su elección (por defecto) y hace VerticalPanel los botones mutuamente excluyentes.

Lo bueno de esto es que el propio panel dispara ClickEvents cuando se hace clic en los botones. De esta manera, se puede añadir una sola clickHandler a la ToggleGroupPanel y luego determinar qué botón se hizo clic usando event.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);
            }
        };
    }

}

Otros consejos

Aquí está mi pura-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);
        }
    }

Sin duda, one'll necesitará estilos css para GWT-ToggleButton con variantes (-up-flotando etc.)

Tengo algo que es a la vez no en una biblioteca de extensión, y no depende de un panel al igual que las otras respuestas. Definir esta clase que gestiona los botones. Estamos añadiendo una nueva escucha clic en los botones, que es además de cualquier controlador de clic que ha conectado en la clase "Contenido interfaz gráfica de usuario". No puedo copiar y pegar esto en, por lo que esperamos es syntatically correcta.

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

   }

  }

encontré con la misma necesidad, aquí tiene otra solución que elimina el controlador independiente y funciona muy bien en UiBinder con una declaración como:

<my:RadioToggleButton buttonGroup="btnGroup" text="Button 1" />

Esta es la clase extendida:

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

gwt-ext

"Este ejemplo ilustra botones de alternancia. Al hacer clic, tales botones de alternar su estado 'presionado'.

Los palanca en negrita, cursiva y subrayado botones funcionan de forma independiente con respecto a su estado de conmutación, mientras que el icono de alineación del texto botones pertenecen a un mismo grupo de palanca y así, cuando uno de ellos es hacer clic, los prensadas previamente se vuelve al estado normal. "

Dar de alta clickHandler adicional sobre todas las ToggleButtons. Por ejemplo, ToggleButtons hogar, árbol, resumen, detalle.

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

Por supuesto, sólo tiene que añadir todos los demás código repetitivo y registrar ClickHandlers adicionales para cada ToggleButton.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top