New API to read Caps-Lock and Num-Lock state
Kevin Rushforth
kevin.rushforth at oracle.com
Tue Jan 19 13:12:10 UTC 2021
I also think that the suggestion of using Optional<Boolean> is a very
good one, and more clearly expresses the "unknown" case without having
to invent a new enum and without the problems that throwing an unchecked
exception could cause.
Thanks.
-- Kevin
On 1/18/2021 12:20 AM, Nir Lisker wrote:
> Looking at the use case for this request, which is to warn the user while
> typing in password fields, I tried to write some simple code for it using
> the Optional approach:
>
> Optional<Boolean> result = Platform.isKeyLocked(KeyCode.CAPS+LOCK);
> result.ifPresentOrElse(on -> label.setText("Caps Lock is " + (on ?
> "on" : "off")),
> () -> label.setText("Check Caps Lock"));
>
> In practical terms, a key event listener would need to be added to the
> password field to react to Caps Lock presses, and that will call the code
> above.
> I think that this is the best option.
>
> On Sun, Jan 17, 2021 at 8:10 PM Frederic Thevenet <thevenet.fred at free.fr>
> wrote:
>
>> I realize that my suggestion was somewhat unclear, apology about that.
>>
>> I wasn't suggesting that we return null to count as the third state, but
>> indeed that we leverage the isPresent state of the optional, alongside
>> with the two states provided by the Boolean, e.g:
>>
>> isKeyLocked(KeyCode.NUM_LOCK).ifPresent(locked-> {
>> // The num_lock key exists on the current platform
>> if (locked){
>> // React to the key being locked
>> } else {
>> // Or to the key not being locked
>> });
>>
>>
>> On 17/01/2021 18:31, Jonathan Giles wrote:
>>> A method returning Optional should never return null, as that undoes
>>> the contract that Optional is supposed to represent, which is to avoid
>>> NPEs by never being null itself, only empty in the absence of a
>>> returned value. For this reason, an Optional should be considered two
>>> state rather than three state.
>>>
>>> -- Jonathan
>>> (Tapped on a touch device)
>>>
>>> On Mon, 18 Jan 2021, 12:29 am Frederic Thevenet,
>>> <thevenet.fred at free.fr <mailto:thevenet.fred at free.fr>> wrote:
>>>
>>> Hi,
>>>
>>> From the perspective of the application developer, I think
>>> throwing a
>>> runtime exception if the key does not exists on a given platform is
>>> potentially risky, as the API provided no hints that a given key
>>> might
>>> not exists an other platforms, and this oversight will only manifest
>>> itself at runtime, on said platform.
>>>
>>> With the other two proposed solution (three-state return and Checked
>>> exception) the API itself reminds its would be consumer that they
>>> should
>>> consider a case where the operation is invalid.
>>>
>>> I'm personally not keen on checked exceptions in such a scenario
>>> either,
>>> as it would require an extra API to check for the existence of a
>>> given
>>> key on the current platform, or condemn developers to implement
>>> conditional logic via exception catching (or require developer to
>>> know
>>> what specific keys exists on what platform before-hand to do the
>>> check).
>>>
>>> Given all that, my personal preference would go to a three state
>>> return
>>> solution.
>>>
>>> On that topic, is there anything that would preclude the use of an
>>> Optional<Boolean> to represent these three states, if we want to
>>> avoid
>>> introducing new enums? It seems to me its semantics aligns quite
>>> nicely
>>> with the problem at hand.
>>>
>>> Fred
>>>
>>>
>>> On 16/01/2021 17:41, Kevin Rushforth wrote:
>>> > Hi Jonathan,
>>> >
>>> > Thanks for the suggestion. I thought about it as well. We could do
>>> > that, but it seems like overkill. I'll reconsider if enough others
>>> > favor the idea. As for the exception, my thinking is to use
>>> > UnsupportedOperationException, which is what the equivalent AWT
>>> method
>>> > uses. FWIW, I don't generally like checked exceptions; we don't
>>> define
>>> > any such exceptions in JavaFX and I wouldn't want to start now.
>>> >
>>> > -- Kevin
>>> >
>>> >
>>> > On 1/16/2021 12:46 AM, Jonathan Giles wrote:
>>> >> Hi friends,
>>> >>
>>> >> Just to throw out an alternate API approach (which I would not go
>>> >> anywhere near close to saying is a better approach), we could
>>> >> consider a three-value enum getter API:
>>> >>
>>> >> public static KeyLockState Platform::getKeyLockState(KeyCode
>>> keyCode);
>>> >>
>>> >> Where KeyLockState = { LOCKED, NOT_LOCKED, NOT_PRESENT }
>>> >>
>>> >> I'll be the first to argue against yet another enum, but I
>>> wanted to
>>> >> throw this out there as an alternate approach that avoids the
>>> needs
>>> >> for checked exceptions (which is what I assume is meant by
>>> 'throw an
>>> >> exception', as opposed to throwing a runtime exception).
>>> >>
>>> >> -- Jonathan
>>> >>
>>> >> On Sat, Jan 16, 2021 at 6:40 AM Kevin Rushforth
>>> >> <kevin.rushforth at oracle.com <mailto:kevin.rushforth at oracle.com>
>>> <mailto:kevin.rushforth at oracle.com
>>> <mailto:kevin.rushforth at oracle.com>>> wrote:
>>> >>
>>> >> For JavaFX 17, I am planning to add a minor enhancement to
>>> read the
>>> >> state of the keyboard lock keys, specifically, Caps-Lock,
>>> >> Num-Lock, and
>>> >> maybe Scroll-Lock (although I might defer the latter to a
>>> future
>>> >> version
>>> >> since it will be more difficult to test, and doesn't seem as
>>> >> useful).
>>> >>
>>> >> This is currently tracked by JDK-8259680 [1].
>>> >>
>>> >> The proposed API would be something like:
>>> >>
>>> >> public static boolean Platform::isKeyLocked(KeyCode
>>> >> keyCode);
>>> >>
>>> >> One question is whether we should throw an exception if the
>>> key
>>> >> state
>>> >> cannot be read on a particular system (e.g., Num Lock on
>>> macOS),
>>> >> which
>>> >> is what the similar AWT API does. I don't have a strong
>>> opinion on
>>> >> that
>>> >> poont, although I wouldn't want to throw an exception if the
>>> >> keyboard
>>> >> doesn't have the key in question, as long the system is able
>> to
>>> >> read the
>>> >> state accurately.
>>> >>
>>> >> Comments are welcome.
>>> >>
>>> >> -- Kevin
>>> >>
>>> >> [1] https://bugs.openjdk.java.net/browse/JDK-8259680
>>> <https://bugs.openjdk.java.net/browse/JDK-8259680>
>>> >> <https://bugs.openjdk.java.net/browse/JDK-8259680
>>> <https://bugs.openjdk.java.net/browse/JDK-8259680>>
>>> >>
>>> >
>>>
More information about the openjfx-dev
mailing list