Javafx spinner not updating properly -- how to debug Javafx source - javafx

I'm using Clojure to implement a JavaFX8 spinner for custom types. The types (defrecords) represent distances of various units, such as um, mm, cm, m, km, inch, mil. So a 10mm distance is #millimeter{:value 10.0}, and can be converted to cm using (cm ...) function, which returns #centimeter{:value 1.0}, etc.
Each instance of spinner is dedicated to showing a particular unit. For example I have one one spinner that always maintains its ValueFactory value using the millimeters defrecord. When the user types a string such as "10", it is taken as millimeters and displayed as 10.0. But when the user types a string such as "10cm", it is converted to millimeters defrecord then displayed as 100.0.
I have implemented SpinnerValueFactory for the spinner, and StringConverter with toString and fromString defined as needed. Everything works great, except sometimes the spinner does not "take" the value when I press enter.
Specifically, if the user types in a string that is equivalent to the value already displayed (for example, "10.0" is displayed for millimeter spinner, and user types "10mm" or "1cm") , then the entire chain of Listeners and var watches I have tied to this thing doesn't fire. I think it's because after converting user's string to millimeters defrecord using, JavaFX determines it's already equal to the ValueFactory value, and decides not to fire the ChangeListener. I can verify that nothing happens even from the REPL where I can forcibly set the value in the ValueFactory.
Questions:
How do I do step-through debug of Javafx source to verify this is happening? I'm pretty crappy with Java, but I have NetBeans and the javafx source.
How do I get JavaFX to force its observables to update?
thanks

I wound up putting an InvalidationListener instead of a ChangeListener on the observable. This gets called even when the observable is set to the same value it already is. This doesn't get the old value like ChangeListener, but I was able to work around that.

Related

Swift Bond 5 migrating from 4 bidirectional

I'm trying to switch to Swift Bond 5 and Swift 3 in one of my projects.
I'm having problem with two direction binding. How can I convert the code below so when my slider is changing it emits distinct signal in steps and set it's value then to the radius observable value. In old Bond 4 and Swift 2.3 everything was working fine but I don't know how to handle this kind of migration.
let radiusSlider: UISlider = /* slider initialisation */
let radius = Observable<Float>(10.0)
let stepValue:Float = 50.0
let sliderStepObserver = radiusSlider.bnd_value.map { roundf($0/stepValue)*stepValue }.distinct()
radiusSlider.value = radius.value
radius.bidirectionalBind(to: sliderStepObserver) /* here is the problem */
The error message is saying:
Argument type 'Signal<Float, DynamicSubject.Error>' (aka 'Signal<Float, NoError>') does not conform to expected type 'BindableProtocol'
So the signal is not bindable anymore. Does somebody have any ideas how to convert this piece of code so the bidirectional binding still will be working?
Bidirectional binding to a transformed signal/observable does not really make sense because it would require inverse transformations to propagate events back.
Instead of a bidirectional binding, you probably want to establish following bindings:
radius.bind(to: radiusSlider)
sliderStepObserver.bind(to: radius)
Also, you'll need to remove that distinct operator or the stepping will not quite work. The reason it will not work is that the user never stops touching screen so we must also never stop updating the slider position to a step value.

QT Creator: Trigger a Slot with Code?

I may have worked myself into a corner but this sounded to me like a good idea at the time.
I have been developing an interface that permits a user to modify settings of a robotic device, i.e. speed, directions, force, etc. with a very large series of options in the form of ComboBoxes. The problem is that there are about a thousand of these things, in sub categories. e.g. Speed category x1, x2, x3, Y1, y2, etc. So rather than create a thousand comboboxes in QT, I thought the good idea was to create one set of 50 (ish) and then provide a few button to switch between categories. So when the user selects speed QT, populates the comboboxes with the appropriate options, sets the style sheets and text for the labels etc. So it appears as though a dedicated page exists. Then if the user selects Direction, QT Writes the current index of each box to a dedicated array and then repopulates the boxes, labels etc with the appropriate content. I then do this over and over for the various needs of the system.
All of that seems to work fine. However I am now in a bind where the options provided to navigate to each page have grown. For instance I have forward / backward buttons (like you woudl expect in a set-up wizard), as well as action menus at the top to jump to a page. So now the code is becoming very repetitious. If you select the next button, I write the current values to array, then repopulate. If you jump to the page from anywhere, I look to see where I am, write it to array, and populate the boxes. Thus if I need to change anything I have to make the change in numerous places in the code.
I know that this is not optimal. What I woudl like to do is run a continuous loop as I woudl normally do with Micros in C. So the program can look at a variable in each pass and if it is then it does. I am not however skilled enough to figure this loop out in QT. So my new thought was...
Is it possible to trigger an action or slot with a variable. For example, if the user presses the Next button it triggers a slot for a button that does not exist, so that QT will execute a particular line of Code? Then I can have 1 dedicated section focused on reading and writing boxes, with a bunch of actions that will take me there.
You can make a signal that is triggered with an emit call in your code, so you'd hook up the next button signal of clicked to a slot that does some work and moves on, or directly calls another signal that you've created that triggers a slot elsewhere, or do some work in a lambda triggered by the button press.
I would first load all the ComboBoxes options in a QStringList array (or maybe an array of QList<QLatin1String> lists - for memory saving and code efficiency).
Then I would keep an array of a 1000 integers for current ComboBox indexes.
When the user changes a value in some ComboBox, the currentIndexChanged signal will trigger the corresponding slot (a single slot for all the ComboBoxes would be enough - sender()->objectName() to get the name of the ComboBox which had sent the signal):
void WindowWidget::on_ComboBox_currentIndexChanged(int index)
{
name = sender()->objectName();
/* here change the corresponding integer in the current
indexes array */
}
On Next/Back button push repopulate the ComboBoxes. Also, provide some 'Save' button for saving the ComboBoxes indexes (or trigger the Save slot on some action, i.e. on window close either even on a timer signal).

How to handle first tab size on formatting?

I create an extension, that format vs editor tabs in custom ways, using ITextParagraphPropertiesFactoryService class. Everything works just fine, expect the fact, that when user enter new line, ITextParagraphPropertiesFactoryService doesnt affect to the new line
For simplifying the problem, I create a new MEF project, add a format provider like this
[Export(typeof(ITextParagraphPropertiesFactoryService))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal class ElasticTabstopsProvider : ITextParagraphPropertiesFactoryService
{
/// <summary>
/// Creates an ElasticTabstopsFormatters for
/// the provided configuration.
/// </summary>
public TextParagraphProperties Create(IFormattedLineSource formattedLineSource, TextFormattingRunProperties textProperties,
IMappingSpan line, IMappingPoint lineStart, int lineSegment)
{
return new TextFormattingParagraphProperties(textProperties, 1);
}
}
And it changes all tabs width from my editor to 1. Great! This is what I want. But now when I press Enter(new line) new cursor is set under Main, however I expect tab widths to be 1.
After I start typing it goes to expected position.
The question is, how can I set new line empty line tab size?
I try to override ISmartIndentProvider, but seems vs ignore that value.
Debuger stops on breakpoint in method
int? GetDesiredIndentation(ITextSnapshotLine currentLine)
of ISmartIndent, but indent stays the same no matter what value I return...
There are at least two reasons why your ISmartIndentProvider's indent is being ignored:
First, there are lots of places with the current C# and VB language services where we explicitly set the caret position in response to certain keypresses. Enter is one of them. It's quite possible that in your scenario, we're explicitly setting the position. Short of disabling smart indenting in Tools > Options, there's nothing you can do to override that. Since you said you're getting a debugger hit in your ISmartIndentProvider, that's probably the issue here.
Second, if you're trying to define a ISmartIndentProvider for content type "text", yours won't get called if there is a language-specific provider. There's also another provider for "text" already (which calls the shimmed old language services) which might win over yours anyways.
To be honest, if you're trying to do something fancy where you don't want automatic indenting, then you really should just turn it off to ensure it's not getting in your way.

flex how to refresh already created view

How can I refresh view after a certain event?
I have a view which contains multiple groups. I want to show or hide some groups.
onCreationComplete() or initialize() method works only at the beginning of the view creation.
Try invalidateDisplayList() on the view
Let me know if that doesn't do the trick and we'll try some other tricks.
I personally don't like the answer that says to call invalidateDisplayList (sorry no offense Nate nothing personal). I feel it's too vague and doesn't explain what this does under the hood and furthermore you shouldn't have to call it directly in cases such as the one explained in the OPs question. You can simply create booleans that are bindable for each of the groups you'd like to show/hide then in the event handler set those booleans to the appropriate value and if they are bound to the visible and include in layout properties of the containers those containers will internally call invalidateDisplayList after calling set visible and consequently commitProperties.
This is basically what happens under the hood as I understand it: The way this works is values aren't committed or used to update the display until the next frame this way it doesn't get bogged down doing unnecessary layout calculations. So you update the bindable property which fires an event which triggers a notification in the listener (in this case a function that sets the property on your control), that in turn passes along the value to the control which sets an internal flag to update the property and calls invalidateProperties. When it hits the next frame redraw it sees that the properties flag is dirty (true) and then calls commitProperties, this computes/sets the appropriate values (possibly also invalidating then "fixing" the size using invalidateSize() and measure()) and calls invalidateDisplayList, then during the same frame it sees that the display list flag is dirty so it calls updateDisplayList, here it uses the values of the properties to draw appropriately.
You should also be able to achieve this using states, which add or remove children from the display list based on an array of "actions" for each state.

Forcing Flex to update the screen?

This may be a bit of a beginners question, but I can't for the life of me figure it out.
I'm using flex to develop a GUI for a large project, specifically a status bar along the bottom. Within my StatusBar class is a ProgressBar, which other classes doing work can tell to update(change bar completion and label) as they progress. The problem I'm encountering is that flex won't update whats shown on the screen until it's too late, for example
ProgressBar initialized, 0% done
some class sets the ProgressBar to be 12% done
some class does some work
some class sets the ProgressBar to be 56% done
Whats happening is the 12% done is never displaying, it just hangs at 0% during the work, then skips right to 56% done. I've tried to understand the lifecycle of a flex component (invalidation and validation), and I think I understand it and am applying it correctly, but it's not working at all. I need to tell flex to redraw my StatusBar (or at least the ProgressBar within) after some class sets it to be 12% done, but before some class starts doing its work. How do I do this?
As mentioned in other answers, the flash player is single threaded, if you don't break up your work into discrete chunks that can be executed in separate "frames", you're going to see jumps and stutters in the ui, which is effectively what you're seeing.
If you really must see that 12% message, then it's not enough to invalidate the display list, as the display list isn't getting a chance to update until after the 56% work has completed, you must explicitly interrupt the natural event cycle with a call to validateNow() after your message has been set.
This however is not the best way to do things if performance is of concern. You might get by with judicial usage of callLater() to schedule each chunk of work in turn, as this will allow the player to potentially complete a frame cycle (and update the display list) before attempting the next step in your process.
Glenn,
That is not at all how the threading in Flex works whatsoever. Like many UIs it has a message pump on the main UI thread (they do it in frames). When you call callLater() it places the passed in function pointer at the end of the message pump queue (on the next frame) and returns immediately. The function then gets called when the message pump has finished processing all of the messages prior (like mouse clicks).
The issue is that as the property change causes UI events to be triggered, they then place their own messages on the pump which now comes after your method call that you placed there from callLater().
Flex does have multiple threads but they are there for Adobe's own reasons and therefore are not user accessible. I don't know if there is a way to guarantee that a UI update will occur at a specific point, but an option is to call callLater a number of times until the operation occurs. Start off with a small number and increase until the number of iterations produces the result you want. Example:
// Change this to a number that works... it will probably be over 1, depending on what you're doing.
private const TOTAL_CALL_COUNT:int = 5;
private var _timesCalled:int = 0;
//----------------------------------------------------------------
private function set Progress( progress:int ):void
{
progressBar.value = progress;
DoNextFunction();
}
//----------------------------------------------------------------
private function DoNextFunction():void
{
if( _timesCalled >= TOTAL_CALL_COUNT )
{
_timesCalled = 0;
Function();
}
else
{
_timesCalled++;
callLater( DoNextFunction );
}
}
Try calling invalidateDisplayList() after each changes to your progress bar. Something like :
Class StatusBar
{
public function set progress(value:uint):void
{
progressBar.value = value;
progressBar.invalidateDisplayList();
}
}
Flex has an invalidation cycle that avoid screen redrawing everytime a property changes. As an example, if a property's value changes 3 times in a single frame, it will render only with the last value set. You can force a component to be redrawn by calling invidateDisplayList() which means updateDisplayList will be immediatly executed instead of waiting the next frame.
Actionscript in Flash player, like Javascript in the browser, is pseudo-multithreaded. That is, they're single threaded, but they have multiple execution stacks. This means you can't "sleep" in a particular thread, but you can spawn a new execution stack that gets deferred until a later time. The flex way of doing this is the "callLater" function. You can also use the setTimeout/setInterval functions. Or you can use a timer object built into the flash player. Or even "ENTER_FRAME" event listener. All of these will essentially allow you to do what you need, if I'm correct about the cause of your problems.
It sounds like you have one "thread" doing most of your work, never stopping to allow other execution stacks (threads*) to run.
The problem could be what PeZ is saying, but if that doesn't help, you might want to try some deferred calls for worker classes. So your process might look like this now:
Progress initialized.
Do some work.
Update progress bar to 12. (invalidate display list)
setTimeout(doMoreWork, 100);
Update progress bar to 52.
(if your worker is a UIcomponent, you can use uicomp.callLater(...), otherwise, you need to use setTimeout/timers/enter_frame for pure AS3 classes).
Sometimes its necessary set to zero before assign another value.
progressBar.setProgress(0, progressBar.maximum);
progressBar.setProgress(newValue, progressBar.maximum);
I'm using Flash Builder 4.6 and I also have a problem for the display of my progress bar. I open a new window where I start a new multiloader class (39 Mo of content). The new window is opened in background and the main window display a progress bar until the multiloader class has finished his work. However the opening window is blocking the animation of my main window. I know it's not the multiloader class cause I saw it running correctly.
But I will try to find some new ways of doing it.
The main purpose of my post is the complexity adobe has build around flash.
When you seek ressources for your own application or answers for your questions, it's a real pain to find the good ressource. There is a total mix up (at adobe side and at user side) between AS3, Flex, Flash CS, Flash Builder, AiR, ... If you try to develop in AS3, you will find that some examples won't work for you because it is not implemented in your SDK. You have more and more forums giving you the "best practice" or ironic answers based on experiences on different developping platform.
By example, just here above, I see progressBar.value = value; With my experience, I can say that in Flash Builder 4.6, this property is read-only. But It might be a custom class made by the user but who can tell.

Resources