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.f...@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.f...@free.fr <mailto:thevenet.f...@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.rushfo...@oracle.com <mailto:kevin.rushfo...@oracle.com>
     <mailto:kevin.rushfo...@oracle.com
     <mailto:kevin.rushfo...@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>>
     >>
     >


Reply via email to