screens in blackberry - user-interface

how can i navigate screens on button click.
there are two buttons , previous and next.
when i click the previous button, a screan1 will be displayed and when i press next ,a screan2 will be displayed and so on.

There are a couple of different ways to do this. The UI library on a Blackberry will maintain a stack of screens for you so you can either:
1) when a button is pressed, create a new screen and push it onto the stack, then remove the old screen and let it be garbage collected; or
2) when a button is pressed, determine if a screen for that button already exists on the stack and move it to the front, or create a new one as above. In this case you don't have to remove the screens, but if you have a lot of complex screens you could run out of resources.
See: net.rim.device.api.ui.UiApplication.pushScreen(Screen screen) and net.rim.device.api.ui.UiApplication.popScreen(Screen screen)

Here's a simple implementation:
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;
public class NavigateScreen extends MainScreen implements FieldChangeListener {
private ButtonField previousButton;
private ButtonField nextButton;
public NavigateScreen() {
add(new LabelField("Some content"));
previousButton = new ButtonField("Previous", ButtonField.CONSUME_CLICK);
previousButton.setChangeListener(this);
nextButton = new ButtonField("Next", ButtonField.CONSUME_CLICK);
nextButton.setChangeListener(this);
add(previousButton);
add(nextButton);
}
public void fieldChanged(Field field, int context) {
if (field == previousButton) {
UiApplication.getUiApplication().popScreen(NavigateScreen.this);
UiApplication.getUiApplication().pushScreen(new PreviousScreen());
}
if (field == nextButton) {
UiApplication.getUiApplication().popScreen(NavigateScreen.this);
UiApplication.getUiApplication().pushScreen(new NextScreen());
}
}
}

Hi I have created a SwitchScreenController class to make switching between screen very easly.
public class SwitchScreenController {
public void switchHomeScreen() {
}
public void switchToHomeScreen() {
//UiApplication.getUiApplication().pushScreen(new HomeScreen());
}
public void switchToProgressingScreen() {
}
public void switchToNextScreen(MainScreen targetScreen) {
UiApplication.getUiApplication().pushScreen(targetScreen);
}
public void switchToPreviousScreen() {
UiApplication.getUiApplication().popScreen(
UiApplication.getUiApplication().getActiveScreen());
}
}
you can use it any where like this.
new
public class SwitchScreenController {
public void switchHomeScreen() {
}
public void switchToHomeScreen() {
//UiApplication.getUiApplication().pushScreen(new HomeScreen());
}
public void switchToProgressingScreen() {
}
public void switchToNextScreen(MainScreen targetScreen) {
UiApplication.getUiApplication().pushScreen(targetScreen);
}
public void switchToPreviousScreen() {
UiApplication.getUiApplication().popScreen(
UiApplication.getUiApplication().getActiveScreen());
}
}
you can go back using
new SwitchScreenController().switchToPreviousScreen();
and to next screen using
new SwitchScreenController().switchToNextScreen(new NextScreen());

Related

JavaFX - Set Slider value after dragging mouse button

I'm writing music player and I don't know how to code slider dragging handler to set value after user frees mouse button. When I write simple MouseDragged method dragging brings non estetic "rewinding" sound because mediaplayer changes value every time slider moves. While playing slider automatic changes value by mediaplayer listener to synchronize with track duration. This is what I got so far.
ChangeListener<Duration> timeListener = new ChangeListener<Duration>() {
#Override
public void changed(
ObservableValue<? extends Duration> observableValue,
Duration duration,
Duration current) {
durSlider
.setValue(current
.toSeconds());
}
};
durSlider.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
mediaPlayer.seek(Duration.seconds(durSlider.getValue()));
}
});
The valueChanging property of the slider indicates if the slider is in the process of being changed. It is an observable property, so you can attach a listener directly to it, and respond when the value stops changing:
durSlider.valueChangingProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> obs, Boolean wasChanging, Boolean isNowChanging) {
if (! isNowChanging) {
mediaPlayer.seek(Duration.seconds(durSlider.getValue()));
}
}
});
This won't change the position of the player if the user clicks on the "track" on the slider, or uses the keyboard to move it. For that, you can register a listener with the value property. You need to be careful here, because the value is also going to change via your time listener. In theory, the time listener should set the value of the slider, and then that should cause an attempt to set the current time of the player to the exact value it already has (which would result in a no-op). However, rounding errors will likely result in a lot of small adjustments, causing the "static" you are observing. To fix this, only move the media player if the change is more than some small minimum amount:
private static double MIN_CHANGE = 0.5 ; //seconds
// ...
durSlider.valueProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> obs, Number oldValue, Number newValue) {
if (! durSlider.isValueChanging()) {
double currentTime = mediaPlayer.getCurrentTime().toSeconds();
double sliderTime = newValue.doubleValue();
if (Math.abs(currentTime - sliderTime) > 0.5) {
mediaPlayer.seek(newValue.doubleValue());
}
}
}
});
Finally, you don't want your time listener to move the slider if the user is trying to drag it:
ChangeListener<Duration> timeListener = new ChangeListener<Duration>() {
#Override
public void changed(
ObservableValue<? extends Duration> observableValue,
Duration duration,
Duration current) {
if (! durSlider.isValueChanging()) {
durSlider.setValue(current.toSeconds());
}
}
};
Here's a complete example (using lambdas for brevity):
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;
import javafx.util.Duration;
public class VideoPlayerTest extends Application {
private static final String MEDIA_URL =
"http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv";
private static final double MIN_CHANGE = 0.5 ;
#Override
public void start(Stage primaryStage) {
MediaPlayer player = new MediaPlayer(new Media(MEDIA_URL));
MediaView mediaView = new MediaView(player);
Slider slider = new Slider();
player.totalDurationProperty().addListener((obs, oldDuration, newDuration) -> slider.setMax(newDuration.toSeconds()));
BorderPane root = new BorderPane(mediaView, null, null, slider, null);
slider.valueChangingProperty().addListener((obs, wasChanging, isChanging) -> {
if (! isChanging) {
player.seek(Duration.seconds(slider.getValue()));
}
});
slider.valueProperty().addListener((obs, oldValue, newValue) -> {
if (! slider.isValueChanging()) {
double currentTime = player.getCurrentTime().toSeconds();
if (Math.abs(currentTime - newValue.doubleValue()) > MIN_CHANGE) {
player.seek(Duration.seconds(newValue.doubleValue()));
}
}
});
player.currentTimeProperty().addListener((obs, oldTime, newTime) -> {
if (! slider.isValueChanging()) {
slider.setValue(newTime.toSeconds());
}
});
Scene scene = new Scene(root, 540, 280);
primaryStage.setScene(scene);
primaryStage.show();
player.play();
}
public static void main(String[] args) {
launch(args);
}
}

ViewPagerIndicator not snapping or displaying pager contents all of a sudden

This is a wierd problem.
This will be a terrible question because I have little to no information.
About two days ago I had the ViewPagerAdapter working just fine. I could swipe and it would switch between views as defined by the adapter.
However, all of a sudden (not by itself, I'm sure I did something) the TitlePagerIndicator doesn't snap to the headings and doesn't display any content. By not snapping I mean that if I drag to the left, the title will sit at 3/4 of the screen instead of snapping to the side and displaying the next page (screenshot below).
I have debugged and instantiate item is called and a proper view is returned.
However, when I open the app I'm getting a lot of warnings like these:
VFY: unable to resolve virtual method 3015: Landroid/widget/LinearLayout;.getAlpha ()F
VFY: unable to resolve direct method 3011: Landroid/widget/LinearLayout;. (Landroid/content/Context;Landroid/util/AttributeSet;I)V
VFY: unable to resolve virtual method 2965: Landroid/widget/FrameLayout;.setAlpha (F)V
I'm assuming this is a problem with my imports, but everything compiles just fine, I have the ViewPagerIndicator as a library project, as well as Sherlock.
Here's my adapter code:
public class ViewPagerAdapter extends PagerAdapter implements TitleProvider {
private static String[] titles = new String[] {
"My Klinks",
"Received Klinks"
};
private final Context context;
public ViewPagerAdapter(Context context) {
this.context = context;
}
public String getTitle(int position) {
return titles[position];
}
#Override
public int getCount() {
return titles.length;
}
#Override
public Object instantiateItem(View pager, int position) {
TextView t = new TextView(context);
t.setText("WheeeE");
return t;
}
#Override
public void destroyItem(View pager, int position, Object view) {
((ViewPager) pager).removeView((TextView) view);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void finishUpdate(View view) {
}
#Override
public void restoreState(Parcelable p, ClassLoader c) {
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate(View view) {
}
}
And here is my activity code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.main );
// set up the slidey tabs
ViewPagerAdapter adapter = new ViewPagerAdapter( this );
ViewPager pager = (ViewPager)findViewById( R.id.viewpager );
TitlePageIndicator indicator = (TitlePageIndicator)findViewById( R.id.indicator );
pager.setAdapter( adapter );
indicator.setViewPager( pager );
// set up the action bar
final ActionBar ab = getSupportActionBar();
ab.setBackgroundDrawable(getResources().getDrawable(R.drawable.ad_action_bar_gradient_bak));
}
If someone else gets the same problem:
In instantiateView: don't forget to attach your new View to the ViewPager:
#Override
public Object instantiateItem(View pager, int position) {
TextView t = new TextView(context);
t.setText("WheeeE");
((ViewPager)pager).addView(t);
return t;
}
The current version of instantiateItem gets a ViewGroup instead of a View, the solution should be the same.
Well after a couple days of banging my head against a wall I've come to the conclusion that my ViewPagerAdapter was the problem.
I simply created a dynamic fragment and created a subclass of FragmentPagerAdapter instead and now it works just fine...

Return from a pushed BlackBerry screen to the parent screen

I have a main menu in Blackberry application. I want to access different screens when I enter the menu items and need to come back to the main menu. How can I do it?
Here is what I tried but caught up a runtime exception when pressed Back button:
package com.stockmarket1;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.decor.*;
import net.rim.blackberry.api.push.PushApplication;
public class StockMarket extends UiApplication implements FieldChangeListener {
public Screen _clientList;
public Screen _comments;
public Runnable _popRunnable;
public static void main(String[] args)
{
StockMarket theApp = new StockMarket();
theApp.enterEventDispatcher();
}
public StockMarket() {
//Code for MainScreen
final MainScreen baseScreen = new MainScreen();
baseScreen.setTitle("Colombo Stock Exchange");
ButtonField clientList = new ButtonField("View Client List", ButtonField.CONSUME_CLICK);
clientList.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
pushScreen(_clientList);
}
});
ButtonField comments= new ButtonField("View Comments", ButtonField.CONSUME_CLICK);
comments.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
pushScreen(_comments);
}
});
Bitmap bitmap = Bitmap.getBitmapResource("logo1.png");
BitmapField logo = new BitmapField(bitmap, BitmapField.FIELD_HCENTER);
LabelField newLine = new LabelField("\n");
baseScreen.add(logo);
baseScreen.add(newLine);
baseScreen.add(clientList);
baseScreen.add(comments);
//Code for _comments
_comments = new FullScreen();
_comments.setBackground(BackgroundFactory.createSolidBackground(Color.LIGHTCYAN));
LabelField title = new LabelField("Comments",LabelField.FIELD_HCENTER);
LabelField comment = new LabelField("Type");
RichTextField rtfComment = new RichTextField();
_comments.add(title);
_comments.add(comment);
_comments.add(rtfComment);
//Code for _clientList
_clientList = new FullScreen();
_clientList.setBackground(BackgroundFactory.createSolidBackground(Color.LIGHTBLUE));
LabelField clientTitle = new LabelField("Listed Companies\n\n", LabelField.FIELD_HCENTER);
LabelField line = new LabelField("__", LabelField.USE_ALL_HEIGHT);
ButtonField closeClient = new ButtonField("Close", ButtonField.CONSUME_CLICK);
closeClient.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
pushScreen(baseScreen);
}
});
_clientList.add(clientTitle);
_clientList.add(line);
//Events
pushScreen(baseScreen);
}
public void fieldChanged(Field field, int context) {
// TODO Auto-generated method stub
}
}
The code for your 'Close' button is a problem, but I think you said you get a RuntimeException when hitting the 'back' button on the device, which I think has a different cause.
Instead of pushing the menu screen onto the screen stack, you should just pop the current screen. This will return to the menu screen that was displayed previously:
closeClient.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
// previous code:
// pushScreen(baseScreen);
// correct code:
popScreen(_clientList);
}
});

Instant value change handler on a GWT textbox

I would like to update a text field instantly when typing in a GWT TextBox. My problem is that ValueChangeEvent and ChangeEvent handlers only fire when the TextBox loses focus. I thought about using the KeyPressEvent but then nothing would happen when performing a copy paste with the mouse.
What's the simplest way to do that ?
You could catch the ONPASTE event and manually fire a ValueChangeEvent. Something like this:
public void onModuleLoad() {
final Label text = new Label();
final ExtendedTextBox box = new ExtendedTextBox();
box.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
text.setText(event.getValue());
}
});
box.addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(KeyUpEvent event) {
text.setText(box.getText());
}
});
RootPanel.get().add(box);
RootPanel.get().add(text);
}
private class ExtendedTextBox extends TextBox {
public ExtendedTextBox() {
super();
sinkEvents(Event.ONPASTE);
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (DOM.eventGetType(event)) {
case Event.ONPASTE:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
ValueChangeEvent.fire(ExtendedTextBox.this, getText());
}
});
break;
}
}
}
Tested on firefox 3.6.1.
As a general solution, what works for me (thx to gal-bracha comment):
Generally, GWT does not have classes to handle input event (described here
and here). So we need to implement it by ourselves:
Handler class:
import com.google.gwt.event.shared.EventHandler;
public interface InputHandler extends EventHandler {
void onInput(InputEvent event);
}
Event class:
import com.google.gwt.event.dom.client.DomEvent;
public class InputEvent extends DomEvent<InputHandler> {
private static final Type<InputHandler> TYPE = new Type<InputHandler>("input", new InputEvent());
public static Type<InputHandler> getType() {
return TYPE;
}
protected InputEvent() {
}
#Override
public final Type<InputHandler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(InputHandler handler) {
handler.onInput(this);
}
}
Usage:
box.addDomHandler(new InputHandler() {
#Override
public void onInput(InputEvent event) {
text.setText(box.getText());
}
},InputEvent.getType());
It works on every TextBox value change including pasting using context menu. It does not react on arrows, ctrl, shift etc...
This has been a major issue for me in the past. The keyupHandler wont work because the copy paste requires a second key press on the paste option which does not fire the event. the best i have been able to do is use the old changelistener not ideal but it does work.
I prefer use Elements than Widgets so this my way to handler.
Element input = Document.get().getElementById("my-input");
DOM.sinkBitlessEvent(input, "input");
DOM.setEventListener(input, event -> GWT.log("Event!"));
Why not use combination of both KeyUpHandler and a ChangeHandler on the TextBox?
Should take care of immediate feedback on each keystroke as well as copy paste case as well.
Just saw this question. Because I was facing the similar problem.
Did some hack and it worked for me.
You can use KeyUpHandler but use it with additional if block that checks
for length of textbox. If length of text box is > 0, do your thing.
Ex:
textBox.addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(KeyUpEvent keyUpEvent) {
if (textBox.getText().length() > 0) {
//do your stuff`enter code here`
}
}

gwt widget - mutually-exclusive toggle button

I want a hybrid of a ToggleButton and RadioButton.
I want the "mutually-exclusive" part of RadioButton, and the gui look and behavior of ToggleButton(up and down states).
Does one already exist?
I've adapted kirushik's solution and created a simple "ToggleButtonPanel" widget that takes an arbitrary number of ToggleButtons (and possibly any other widgets you'd like to add) and a panel of your choosing (defaults to VerticalPanel) and makes the buttons mutually exclusive.
What's nice about this is that the panel itself fires ClickEvents when the buttons are clicked. This way, you can add a single ClickHandler to the ToggleGroupPanel and then determine which button was clicked using 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);
}
};
}
}
Here is my pure-gwt variant:
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);
}
}
Surely, one'll need css styles for gwt-ToggleButton with variants (-up-hovering etc.)
I have something that is both not in an extension library, and not dependent on a panel like the other answers. Define this class which manages the buttons. We're adding a new click listener to the buttons, which is in addition to whatever click handler you attached in the "GUI Content" class. I can't copy and paste this in, so hopefully it's syntatically correct.
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);
}
}
}
Came across the same need, heres another solution that does away with the separate handler and works nicely in UIBinder with a declaration like:
<my:RadioToggleButton buttonGroup="btnGroup" text="Button 1" />
Here's the extended class:
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 );
}
}
}
gwt-ext toggleButtons
"This example illustrates Toggle Buttons. When clicked, such Buttons toggle their 'pressed' state.
The Bold, Italic and Underline toggle Buttons operate independently with respect to their toggle state while the text alignment icon Buttons belong to the same toggle group and so when one of them is click, the previously pressed Button returns to its normal state."
Register an additional ClickHandler on all the ToggleButtons.
For example, ToggleButtons home, tree, summary, detail.
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);
}
}
Of course, you just need to add all the other boilerplate code and register additional ClickHandlers for each ToggleButton.

Resources