Chcę hybrydy ToggleButton i RadioButton. Chcę mieć "wzajemnie wyłączną" część RadioButton, a także wygląd i zachowanie GUI ToggleButton (stany góra i dół). Czy już istnieje?widget gwt - wzajemnie wyłączający przycisk przełączania
Odpowiedz
Mam przystosowane kirushik'S rozwiązanie i stworzył prosty widget "ToggleButtonPanel", który przyjmuje dowolną liczbę przycisków ToggleButtons (i ewentualnie innych widżetów, które chcesz dodać) oraz wybrany panel (domyślnie VerticalPanel) i sprawia, że przyciski wzajemnie się wykluczają.
Zaletą jest to, że sam panel uruchamia ClickEvents po kliknięciu przycisków. W ten sposób, można dodać jeden clickHandler do ToggleGroupPanel a następnie ustalić, który przycisk został wciśnięty przy użyciu 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);
}
};
}
}
„Przykład ten ilustruje Przegubowe przycisków. Po kliknięciu takie przyciski przełączników ich«wciśnięty»stanu.
Bold, kursywa i dolna przerzutowe Przyciski działać niezależnie w odniesieniu do ich stanu przełączania natomiast ikona wyrównania tekstu Przyciski należą do tej samej grupy przełączania, więc gdy jedno z nich kliknie, poprzednio naciśnięty przycisk powraca do normalnego stanu. "
Oto moja czystej GWT wariant:
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);
}
}
pewnością one'll trzeba stylów CSS dla gwt-ToggleButton z wariantów (up-unosić itp)
Nie pamiętam, dlaczego chciałem tego, ale +1 dla odpowiedzi. –
Dzięki, to nie jest taka wielka sprawa - to tylko wklej z mojego obecnego projektu :) – kirushik
mam coś, co jest zarówno w bibliotece nie przedłużacza, a nie zależy od panelu podobnie jak inne odpowiedzi. Zdefiniuj tę klasę, która zarządza przyciskami. Dodajemy nowy przycisk nasłuchiwania kliknięcia do przycisków, który jest dodatkiem do instrukcji obsługi kliknięcia dołączonej do klasy "GUI Content". Nie mogę tego skopiować i wkleić, więc mam nadzieję, że jest poprawna pod względem składni.
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);
}
}
}
Zarejestruj dodatkowe narzędzie ClickHandler we wszystkich przyciskach ToggleButtons. Na przykład, ToggleButtons dom, drzewo, podsumowanie, szczegół.
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);
}
}
Oczywiście, wystarczy dodać wszystkie inne kody szablonowe i zarejestrować dodatkowe ClickHandlers dla każdego ToggleButton.
Natknąłem tym samym potrzebującym, heres inne rozwiązanie, które eliminuje osobnej obsługi i działa dobrze w UiBinder z oświadczeniem, takich jak:
<my:RadioToggleButton buttonGroup="btnGroup" text="Button 1" />
Oto rozszerzona klasa:
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);
}
}
}
Ale ci nie ma właściwości wzajemnego wykluczania przycisków radiowych (np. kliknięcie jednego, a następnie kliknięcie innego i wybór dwóch przycisków). –