Kotlin|Tornadofx: How to open new fxml screen on mouse click in another fxml screen - kotlin

I have a very simple task but can't do it.
I have Kotlin|Tornadofx app.
I open the fxml screen:
class MainView : View() {
override val root : VBox by fxml("/Screen 1.fxml")
}
There is a button in Screen1.fxml. I need the app to open another screen (Screen2.fxml) on button pressed in Screen1.fxml.
I got stuck by this. Only a function call is available from Screen1.fxml by means of onAction="#FunctiondefinedinMainView". But swapping views in MainView is only available by
button("Go to Screen2") {
action {
replaceWith<Screen2>()
}
constructs, which I cannot accomplish because I only can call a function from within Screen1.fxml. And I do not have buttons in MainView.
Thanks in advance.

First, you should add an id to your button in your Screen 1.fxml file:
<Button fx:id="myButtonId">
Then, you can get a reference to that button in your MainView:
class MainView : View() {
override val root: VBox by fxml("/Screen 1.fxml")
val button: Button by fxid("myButtonId")
}
Now, you can set the click listener for your button to replace the screen:
class MainView : View() {
override val root: VBox by fxml("/Screen 1.fxml")
val button: Button by fxid("myButtonId")
init {
button.setOnAction {
replaceWith<Screen2>()
}
}
}
I haven't tried this before but it should work, in case it doesn't, feel free to leave a comment.

Related

How to open (enter) SettingsFragment or any Fragment on Android (Kotlin)

I am learning Android programing, and I can not figure it out how to open settings fragment when button is clicked.
This fragment is not in the navigation map, so it is not possible to connect them in navigation and to use findNavController().navigate(actionFromTo)
As explained on developer guide: https://developer.android.com/guide/topics/ui/settings
I have created fragment:
class PreferencesFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
}
}
What I need to write in click listener to enter settings fragment?
Click listener is:
binding.buttonSettings.setOnClickListener {
}
I have tried with to use code in developers guide:
binding.buttonSettings.setOnClickListener {
val fragmentManager: FragmentManager? = activity?.supportFragmentManager
fragmentManager?.beginTransaction()?.replace(R.id.preferencesFragment, PreferencesFragment())?.commit()
}
But program crashes when button is pressed, with error:
No view found for...
The issue seems to be the content ID you want to replace, therefore you need to pass the current content ID you want to replace
see below code, use android.R.id.content instead of R.id.preferencesFragment
binding.buttonSettings.setOnClickListener {
val fragmentManager: FragmentManager? = activity?.supportFragmentManager
fragmentManager?.beginTransaction()?.replace(android.R.id.content, PreferencesFragment())?.commit()
}

Listener for panel inside card layout ( which ll be fired every for panel) ???

I have a card layout, Inside card there are many panels inside card items.
I want some listener which will be fired as soon as panel inside card layout is visually activated.
i was trying to achieve the same with Activate and show event,but i am not getting desired output.
One approach would be to write a controller that references all the views, if you are using the MVC pattern:
Ext.define('MyApplication.controller.PanelsController', {
extend : 'Ext.app.Controller',
itemId : 'panelsController',
views : [
'Panel1',
'Panel2' // etc...
],
init : function (application) {
this.control(
{
'panel#panel1' : {
show : this.myListener
}
});
},
myListener : function () {
// do stuff here.
}
});

Show & Hide events for a Sencha Touch navigation view

I'd like to be able to hide and show certain buttons in a navigation view bar when a view is push and popped onto the view stack. Shame I can't control that from the view config itself (but I'll save that moan for another time).
I wanted to know which events I should be using when a view is push/popped on a navigation view. The docs sometimes lie and I've been told many times not too trust it, so I'm not! Come on Sencha, Microsoft wouldn't get away with this!
So Any ideas? When I try to print out all the events for a view I get very unreliable behaviour:
What I've found:
When I push a view I get:
initialize
hide
show
When I pop a view I get:
hide
show
What the flip is going on?!?
The code to show events happening:
control: {
myViewRef: {
initialize: function() { console.log("initialize") },
activated: function() { console.log("activated") },
deactivated: function() { console.log("deactivated") },
painted: function() { console.log("painted") },
show: function() { console.log("show") },
hide: function() { console.log("hide") }
},
}
The code to actually push/pop a view:
onInBoxListViewItemTap: function(scope, index, item, record) {
console.log("onInBoxListViewItemTap");
var detailsView = this.getEnquiryDetailsViewRef();
// push view
var navview = this.getMyInboxViewRef();
navview.push(detailsView);
}
Does this stuff actually work properly i.e. Are there concrete events which are guaranteed to fire when a view is pushed and popped?
First of all - you have a typo in your code. You need to reference activate and deactivate not activate_d and deactivate_d.
Second, I would try to subscribe to push and pop events of navigation view and see if it would get you what you want.
I have the same problem.I use painted handler to solve it.
You can't handle 'painted' event in controller
the painted event description

Sencha Touch 2 Navigationview pop and push event listener

I have a navigationView with some items on it, if I pop the item, and push a modified one back, the event listeners in my controller no longer trigger. How can I get them to work again? I don't get it because each item destroyed and created from scratch when I push it back. Autodestroy is enabled.
//Add a view
this.view = Ext.create('ec.view.view1')
this.getNavigation().push(this.view);
//Remove a view (or press back in the navigationview)
this.getNavigation().pop();
//Add a fresh view back
this.view = Ext.create('ec.view.view1')
this.getNavigation().push(this.view);
Controller tap handler
refs {
button : '#button'
},
control : {
button : {
tap: 'OnTap'
}
},
OnTap: function() { console.log("Tap") }
With the above, all the events, taps, etc break for the view
I had the same issue, search for loads of forums, lost lots of time, got angry about Sencha support and finally moved the button handler code from the controller back into the view:
xtype: 'button',
text: 'Save',
handler: function(button, event) {
console.log('button pressed');
}
"Dirty", but it works.
I suspect the cause of this behavior is NavigationView.pop() destroying the actual NavigationView, but not it's subordinate objects.

Double click on buttons inside the app could provide UI corruptions

Double clicking fast on a button in Sencha Touch 2 when having a navigation view will on some Android device push the new view twice on the view stack, how to solve it? Doesnt happen on iPhone
If you're having problems with the single click, then wrap the event function in a delayed task... for instance:
tap: function(button, e, eOpts) {
if(this.delayedTask == null){
this.delayedTask = Ext.create('Ext.util.DelayedTask', function() {
this.myFunctionToCall();
this.delayedTask = null;
}, this);
this.delayedTask.delay(500);
}
}
So in the example above, if another tap is registered and this.delayedTask has yet to be null, then it will not create the new delayed task which ultimately calls whatever function you need after 500 miliseconds... hope this makes sense, it's also a way to create double tap events on buttons...
This issue is a bit old but I was facing the same issue in the app I'm working on in my company. This is especially frustrating when buttons are bound to an Ajax call.
I took back Jeff Wooden's solution to override every button in my app :
Ext.define('MyApp.override.CustomButton', {
override : 'Ext.Button',
doTap: function(me, e) {
if(this.delayedTask == null){
this.callOverridden(arguments);
this.delayedTask = Ext.create('Ext.util.DelayedTask', function() {
this.delayedTask = null;
}, this);
this.delayedTask.delay(500);
} else {
console.log("Preventing double tap");
}
}
});
How does it works?
Each button action will trigger a delayedTask which will intercept button action for 500 ms, therefore preventing doubletap
This will work for 'tap' and 'handler:', which both pass through 'doTap' method
this is linked to the current button so it won't reverberate on other buttons
To use it simply add it in your app.js 'requires' block
Ext.application({
requires: [
...
'MyApp.override.CustomButton',
...
],
Helpfull Sources :
https://www.sencha.com/forum/showthread.php?173374-Ext-override()-on-Ext-components-in-ExtJS-4-x
Best practice for overriding classes / properties in ExtJS?
this post