5

我想要一个ToggleButtonRadioButton的混合体。我想要 RadioButton 的“互斥”部分,以及 ToggleButton 的 gui 外观和行为(向上和向下状态)。是否已经存在?

4

6 回答 6

9

我已经调整了 kirushik 的解决方案并创建了一个简单的“ToggleButtonPanel”小部件,它采用任意数量的 ToggleButtons(可能还有您想要添加的任何其他小部件)和您选择的面板(默认为 VerticalPanel)并使按钮相互独家的。

这样做的好处是,当单击按钮时,面板本身会触发 ClickEvents。这样,您可以将单个 ClickHandler 添加到 ToggleGroupPanel,然后使用 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);
            }
        };
    }

}
于 2011-01-18T20:57:26.043 回答
3

这是我的纯 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);
        }
    }

当然,gwt-ToggleButton 需要带有变体(-up-hovering 等)的 css 样式

于 2010-02-04T13:02:17.327 回答
3

我有一些既不在扩展库中,也不像其他答案那样依赖于面板的东西。定义管理按钮的此类。我们正在向按钮添加一个新的单击侦听器,这是您在“GUI 内容”类中附加的任何单击处理程序的补充。我不能复制和粘贴这个,所以希望它在语法上是正确的。

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

   }

  }
于 2013-01-21T14:22:05.880 回答
1

遇到了同样的需求,这是另一个解决方案,它取消了单独的处理程序,并在 UIBinder 中很好地工作,声明如下:

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

这是扩展类:

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 );
        }
    }
}
于 2014-07-22T22:17:51.310 回答
0

gwt-ext 切换按钮

“此示例说明了切换按钮。单击时,此类按钮会切换其“按下”状态。

粗体、斜体和下划线切换按钮相对于它们的切换状态独立操作,而文本对齐图标按钮属于同一切换组,因此当其中一个被单击时,先前按下的按钮返回其正常状态。”

于 2009-09-22T19:34:54.673 回答
0

在所有 ToggleButtons 上注册一个额外的 ClickHandler。例如,ToggleButtons 主页、树、摘要、详细信息。

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

当然,您只需要添加所有其他样板代码并为每个 ToggleButton 注册额外的 ClickHandler。

于 2013-03-20T02:51:57.200 回答