-
Notifications
You must be signed in to change notification settings - Fork 479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8242553: IntegerSpinner and DoubleSpinner do not wrap around values correctly in some cases #1431
Conversation
👋 Welcome back drmarmac! A progress list of the required criteria for merging this PR into |
@drmarmac This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 41 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@andy-goryachev-oracle, @karthikpandelu) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
Webrevs
|
Reviewers @andy-goryachev-oracle @karthikpandelu /reviewers 2 |
@kevinrushforth |
@drmarmac It is generally best to ask whether an assigned bug is actively being worked on before submitting a PR. In this case, I suspect it wasn't being worked on. I've asked the assignee (Karthik) to be one of the reviewers. |
ok, thanks for the notice! |
@karthikpandelu I've updated the spinner page in the monkey tester #1406 so we can use it to test this PR (totally missed that this page was incomplete). |
I am a bit uneasy with the proposed solution. Let me explain: The first thing that seems weird to me is the mere existence of increment(int)/decrement(int). Well, it is an existing API, and probably there are some use cases that I cannot immediately see. The real issue is when we have wrapAround enabled and either a large amountToStepBy or the argument for increase/decrease exceeding the (max - min) value. This simply makes no sense, and the modulo arithmetic produces, in my opinion, an unexpected user experience. What I mean is that some combinations of Spinner settings would result in apparently "random" jumps (from the user perspective). What I think should be done is - when this scenario is detected - the adjustment should default to maybe 1 (or (max - min)/10 in the case of the DoubleSpinnerValueFactory). The goal is to fall back gracefully to something a human can understand - and a modulo division is not one of those. What do you think? |
There is one more unexpected behavior - I am going to mention it here, but it might need to be extracted into its own ticket (if people agree it's a bug): Consider a Spinner with a ListSpinnerValueFactory, initialized with a list of values let's say [ "one", "two", "three", "four" ]. What do you think? |
Why? This is entirely under app control. Is it useful to pass an increment that will produce a step larger than the range? Maybe not, but restricting it doesn't see like the right solution, at least not without a good reason to do so. The "obvious" thing is to do modulo arithmetic, which is what this PR aims to do. By "obvious" thing to do, it is the mathematically correct thing to do. It makes a single step of 10 equivalent to 10 steps of 1 regardless of the min / max.
And I would argue that either of those choices is more arbitrary and confusing than the proposed solution, and not appreciably better than what is done today. I see two sensible solutions:
Choice 1 seems best unless there is a down-side that I haven't considered. |
This is definitely unrelated to this bug, so should be discussed separately. I can see your point, but this would be more than just a bug fix -- it would be a behavioral change that we would need to carefully consider. |
try this: integer spinner, min=0. max=100, step=137. initial value 50 makes no sense. falling back to step=1: 49, 48, 47, 46, ... |
But if that's what the app says to do, and given that it's a well-defined operation (albeit not very useful in this example), there should be a good reason to ignore it. I'm not convinced that there is, but if there is, option 3 isn't it.
That's at least as arbitrary as clamping to the max value (the status quo). Clamping the result to the max says, in effect, "let's ignore the |
I don't see that much value in any threshold like |
afair, we already had extensive discussions in #174 (and the related bug and the mailing list - too lazy to read up on all that) agreeing that modulo math (correctly done!) fits common client programmers' expectations most - doesn't matter the step size. |
Let's proceed with the current plan of correctly-implemented modulo arithmetic. I can't think of a compelling reason to do otherwise. |
If everyone is ok with modulo arithmetic. Please clarify the expected behavior in the case of an integer spinner with {min=0; max=100; amountToStepBy=101} and initial value of 0. What should the increment action result in? (0 + 101) % (100 - 0) + 0 = 1 the code in this PR produces no movement (0). Same for the decrement. Is this correct? |
which means that the modulo arithmetic is not yet quite correct (not that the modulo behavior as such is wrong ;) nice test case, btw ;) |
As a user, I would be very surprised with the behavior based on modulo arithmetic. But I do acknowledge the point made by Kevin - if this is what the application developers wanted, then it is their fault. |
The code, as currently suggested, effectively calculates
So your example should result in |
the end result of stepping once by so the formula for positive
or something along these lines. |
Yes, this is the expectaion.
Not quite. Because the range is inclusive on both ends, the number of discrete positions is |
you are right! my earlier comment is invalid. please ignore. Now, when wrapping occurs, should max/min be considered as valid steps? Example, try both integer and double spinners with {min=0, max=10, step=7} starting with value=0. try incrementing. integer: 0, 7, 3, 10 And another question: should the new behavior (whatever everyone agrees to eventually) be documented? Where? This PR? JBS? Javadoc? A markdown file in doc-files/behavior/? Does it need a CSR? |
For integer values (including list indices), yes, since each integer (or list index) is a discrete value that can have the value min, max, or any value in between. And a step of one when you are at "max" should wrap around to "min" For double... that's a good question. I need to think about it a bit. Often when doing wrap-around for floating-point values (think rotation transforms) we treat max and min the same -- although usually that means treating the range as exclusive of max, and that isn't what is current done for double values of spinner.
The integer is working as I would expect (and the next value should be "6").
If we want to specify the functionality, it needs to be documented in the javadoc-generated API docs. That's the specification. Given that this is a clarification of what we mean by "wrapping" and not a fundamental change, we could either do that as part of this enhancement request or a separate one.
The current spec is sufficiently vague on what the wrapping algorithm is that as long as we aren't changing anything fundamental, I don't think we do need a CSR. If we end up changing the spec to document the wrapping algorithm (either as part of this PR or separately), then the change in spec would need a CSR. |
I see these possible definitions for the double spinner behavior with wraparound:
|
1 seems arbitrary and wrong. Neither of the above options make any sense for the sort of things you would use a wrap-around double spinner for. So that leaves 3 and 4. I was leaning towards recommending something like 4 even before you posted it, and the more I think about it, the more it seems like the best option to me. |
…y wrap-around logic
I've updated the behavior for the double spinner according to option 4. Consequences of this approach are:
|
It looks like the issue JDK-8193286 is also fixed by this change, so it probably should be added to this PR. Also, this PR changes the way {List|Integer|Double}ValueFactory behaves when wrapping is enabled, so even though we determined that no CSR is required, I feel we need to document the new behavior in the ticket. So here my suggestions:
otherwise, lgtm. |
/issue add JDK-8193286 |
@drmarmac |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. This PR fixes both the issues mentioned.
Like @andy-goryachev-oracle mentioned, better to describe new behaviour in JDK-8242553 description.
/integrate |
/sponsor |
Going to push as commit d03b002.
Your commit was automatically rebased without conflicts. |
@karthikpandelu @drmarmac Pushed as commit d03b002. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Thanks for getting this fixed. @andy-goryachev-oracle We might want to consider a follow-on fix to change the spec (with a CSR) to document this. What do you think? |
I like the idea of updating the spec (for SpinnerValueFactory.[Integer|Double}SpinnerFactory classes). Do we really need the CSR for clarifying the behavior? |
Can you file a JBS issue to track this?
If it really is just clarifying the existing behavior, maybe not. I'd like to see the changes and then decide. |
Created https://bugs.openjdk.org/browse/JDK-8331214 @drmarmac would you like to update the javadoc or provide the description of the new behavior? |
thanks for creating the issue, I can create the PR. |
thank you! |
This PR should fix the issue and cover all relevant cases with new tests.
Note: This involves a small behavior change, as can be seen in dblSpinner_testWrapAround_decrement_twoSteps() in SpinnerTest.java:749. With this change the wraparound behavior is similar to that of the IntegerSpinner.
Progress
Issues
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1431/head:pull/1431
$ git checkout pull/1431
Update a local copy of the PR:
$ git checkout pull/1431
$ git pull https://git.openjdk.org/jfx.git pull/1431/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1431
View PR using the GUI difftool:
$ git pr show -t 1431
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1431.diff
Webrev
Link to Webrev Comment