JavaFX FXML - Does Button have OnEdit Like Method? - javafx

I have a class that extends Button where a String is constructed like so,
text = button.getText();
However, I need to always update text when it changes i.e. a listener. Does Button have a method like onEdit where I can make sure the button's text is always the same as the variable text?

Register a listener with the button's text property:
button.textProperty().addListener((obs, oldText, newText) -> {
// do whatever you need with newText
});

Related

Xamarin.Forms.EntryCell: How to trigger the event while input any key

I have a problem with Xamarin.Forms.EntryCell. I want to know how to trigger an event if the text of the EntryCell has changed. Not the event 'Completed', it is just triggered when I press Enter after inputting anything.
<EntryCell
Label="User Id"
x:Name="UserIdEntryCell"
HorizontalTextAlignment="End"
Completed="UserIdCompleted"/>
Obviously there is no event that is fired when the text is changed (see the docs). Anyway, this does not mean that you can't achieve what you want, by means of Text property. Since you are using the event I do not assume that you use MVVM (you should really give it a try, though), hence we'll have to create a property we will bind the EntryCell.Text to in your view (I'm assuming a view, but for a page it would be quite similar)
In your code behind add a property Text that calls HandleTextChanged from its setter:
class MyView : ContentView
{
string _text;
public string Text
{
get => _text;
set
{
_text = value;
HandleTextChanged();
}
}
private void HandleTextChange()
{
// do whatever you need to do
}
}
You can bind this property to EntryCell.Text from your XAML
Now MyView.Text will be set every time the text in your EntryCell changes.

How do I create a JavaFX Alert with a check box for "Do not ask again"?

I would like to use the standard JavaFX Alert class for a confirmation dialog that includes a check box for "Do not ask again". Is this possible, or do I have to create a custom Dialog from scratch?
I tried using the DialogPane.setExpandableContent() method, but that's not really what I want - this adds a Hide/Show button in the button bar, and the check box appears in the main body of the dialog, whereas I want the check box to appear in the button bar.
Yes, it is possible, with a little bit of work. You can override DialogPane.createDetailsButton() to return any node you want in place of the Hide/Show button. The trick is that you need to reconstruct the Alert after that, because you will have got rid of the standard contents created by the Alert. You also need to fool the DialogPane into thinking there is expanded content so that it shows your checkbox. Here's an example of a factory method to create an Alert with an opt-out check box. The text and action of the check box are customizable.
public static Alert createAlertWithOptOut(AlertType type, String title, String headerText,
String message, String optOutMessage, Consumer<Boolean> optOutAction,
ButtonType... buttonTypes) {
Alert alert = new Alert(type);
// Need to force the alert to layout in order to grab the graphic,
// as we are replacing the dialog pane with a custom pane
alert.getDialogPane().applyCss();
Node graphic = alert.getDialogPane().getGraphic();
// Create a new dialog pane that has a checkbox instead of the hide/show details button
// Use the supplied callback for the action of the checkbox
alert.setDialogPane(new DialogPane() {
#Override
protected Node createDetailsButton() {
CheckBox optOut = new CheckBox();
optOut.setText(optOutMessage);
optOut.setOnAction(e -> optOutAction.accept(optOut.isSelected()));
return optOut;
}
});
alert.getDialogPane().getButtonTypes().addAll(buttonTypes);
alert.getDialogPane().setContentText(message);
// Fool the dialog into thinking there is some expandable content
// a Group won't take up any space if it has no children
alert.getDialogPane().setExpandableContent(new Group());
alert.getDialogPane().setExpanded(true);
// Reset the dialog graphic using the default style
alert.getDialogPane().setGraphic(graphic);
alert.setTitle(title);
alert.setHeaderText(headerText);
return alert;
}
And here is an example of the factory method being used, where prefs is some preference store that saves the user's choice
Alert alert = createAlertWithOptOut(AlertType.CONFIRMATION, "Exit", null,
"Are you sure you wish to exit?", "Do not ask again",
param -> prefs.put(KEY_AUTO_EXIT, param ? "Always" : "Never"), ButtonType.YES, ButtonType.NO);
if (alert.showAndWait().filter(t -> t == ButtonType.YES).isPresent()) {
System.exit();
}
And here's what the dialog looks like:

How can I listen for focusIn and focusOut events for a Spark TextArea?

I am writing a flex application and I have two Spark TextAreas. I want to create an EventListener so that when the user clicks on a text area, the text inside the TextArea is cleared:
this.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
private function onFocusIn(ev:FocusEvent):void {
if (this._showsCaption) {
this._showsCaption = false;
super.text = "";
}
}
Currently I can implement this with a Spark TextInput, but when I click on the TextArea, the focusIn event never fires and the onFocusIn() handler is never called.
Any thoughts would be much appreciated.
When you are extending the TextArea (as in your case), you can override the protected "focusInHandler" method. This is the handler that is called when the control gets focus. The same goes for the "focusOutHandler" method.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/core/UIComponent.html#focusInHandler()

Dispatch an event from a class that inherits from EventDispatcher

I've got a class that extends EventDispatcher.
What I want to do is to dispatch the click event when the component is clicked. (The class is essentially some text in a textfield that needs to be able to do certain things, and it needs to be able to respond to a click). Sounds easy enough... I want the event dispatched when that portion of the text is clicked. But uh...how? it's not like a button where I can just go
myButton.addEventListener(MouseEvent.CLICK, myClickHandler);
That's clear, because some component is going to be listening for the Click event dispatched when myButton is clicked. It is built into the AS3 framework that a button knows how to listen for a click event.
After the import statements I've got:
[Event(name="click" type="mx.events.Event")]
How do I dispatch the event when the component is clicked, when the component doesn't yet know how to respond to a click event? I've tried adding an event listener in the textfield which contains this custom class of text, but nothing's happening because the Click event hasn't been dispatched.
You can create your own click event and dispatch it. You can do that also to dispatch clicks on objects where no user ever have clicked :D
Try this:
var mEvent:MouseEvent = new MouseEvent(MouseEvent.CLICK, [HERE MORE PARAMS BY YOU]);
yourObject.dispatchEvent(mEvent);
Now, you will recieve Click Events from yourObject.
Let's say your class consists TextField tf. Then public function YourClass():void { //Constructor
{
//intialize Something
//initialize tf
tf.addEventListener(MouseEvent.CLICK, onClick);
...
}
...
private function onClick(e:MouseEvent):void {
this.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
OK, I tried this in the constructor:
var mEvent:MouseEvent = new MouseEvent(MouseEvent.CLICK, true, false);
this.dispatchEvent(mEvent);
Then, in the containing textfield, while iterating through these objects (each of which is called cp), I did this:
cp.addEventListener(MouseEvent.CLICK, mouseClickHandler);
Finally the mouseClickHandler:
private function mouseClickHandler(event:MouseEvent):void
{
trace("Clicked!!!!!!!!!!!");
}
Running in debug mode I get nada. Nunca. Niente. Nuttin'. Which is to say: no trace of being clicked. Did I do something wrong?

How can I tab accross a ButtonBar component in Flex?

I have a button bar inf flex along with several other input controls, I have set the tabIndex property for each control and all goes well until I tab to the ButtonBar.
The ButtonBar has 3 buttons but tabbing to it, only the first button gets focus, tab again and the focus goes back to the top control...
How can I make tabbing go through ALL buttons in a Flex Button bar? Is there a way to do this or do I need to create individual buttons for this?
This seems like a possible bug to me...
The component is written so the user must press the left/right arrow keys when focus is within the bar to traverse the buttons--this is a fairly standard GUI behavior (you also see this in other places like radio button groups). If you look into the SDK source for ButtonBar, you can see where they've explicitly disabled tab focus for each child button as it's created:
override protected function createNavItem(
label:String,
icon:Class = null):IFlexDisplayObject
{
var newButton:Button = Button(navItemFactory.newInstance());
// Set tabEnabled to false so individual buttons don't get focus.
newButton.focusEnabled = false;
...
If you really want to change this behavior, you can make a subclass to do it, something like this:
package {
import mx.controls.Button;
import mx.controls.ButtonBar;
import mx.core.IFlexDisplayObject;
public class FocusableButtonBar extends ButtonBar {
public function FocusableButtonBar()
{
super();
this.focusEnabled = false;
}
override protected function createNavItem(
label:String, icon:Class=null):IFlexDisplayObject
{
var btn:Button = Button(super.createNavItem(label, icon));
btn.focusEnabled = true;
return btn;
}
}
}

Resources