2009-08-29 13 views

Respuesta

9

he adaptado de kirushik solución 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) VerticalPanel y hace que los botones se excluyen mutuamente.

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

} 
0

gwt-ext toggleButtons

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

La negrita, cursiva y subrayado botones de alternancia funcionan independientemente con respecto a su estado de palanca mientras que la icono de alineación de texto Los botones pertenecen al mismo grupo de alternancia y, por lo tanto, cuando uno de ellos hace clic, el botón presionado vuelve a su estado normal ".

+0

Pero aquellos no tiene la propiedad de exclusión mutua de los botones de opción (es decir, hace clic en uno, luego hace clic en otro y tiene dos botones seleccionados). –

3

Aquí es mi variante pura-GWT:

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

Seguramente, one'll necesita estilos css para GWT-ToggleButton con variantes (-up-flotando etc.)

+0

No recuerdo por qué quería esto, pero +1 por la respuesta. –

+0

Gracias, eso no es un gran problema, esto es solo una pega de mi proyecto actual :) – kirushik

3

tengo algo que es a la vez no en una biblioteca de extensión, y no depende de un panel como las otras respuestas. Defina esta clase que administra los botones. Estamos agregando un nuevo detector de clics a los botones, que se suma al controlador de clic que adjuntó en la clase "Contenido de la GUI". No puedo copiar y pegar esto, así que espero que sea sintácticamente correcto.

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

    } 

    } 
0

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.

1

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" /> 

Aquí está 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); 
     } 
    } 
} 
Cuestiones relacionadas