-
Notifications
You must be signed in to change notification settings - Fork 8
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
Feature request: Input map stack #8
Comments
If
|
Another possibility is to offer a delegate:
|
I'm looking at this again. Essentially, what you want is an API to temporarily swap out one set of |
Mostly, the following line, which obtains the editor's current input map, should be replaced with an API that is not so tightly-coupled: nodeMap = (InputMap<InputEvent>)getEditor().getProperties().get(
"org.fxmisc.wellbehaved.event.inputmap" ); Generally speaking, the ability to easily switch // Get the current (default) map.
InputMap<InputEvent> originalMap = getEditor().getInputMap();
// Create the replacement map.
InputMap<InputEvent> mySpecialKeyboard = getKeyboardMap();
// Swap out the editor's map.
getEditor().setInputMap( mySpecialKeyboard );
// Restore original map.
getEditor().setInputMap( originalMap ); The calling code can be responsible for restoring previous state. |
While I was working on #18, I saw that |
@DaveJarvis Can I get your feedback on the API in my PR? |
An absolutely trivially minor part of the code to consider changing is: node.getProperties().put(...);
node.getProperties().get(...); This is a minor form of duplication and a minor violation of the Law of Demeter. Instead: node.putProperty(...);
node.getProperty(...); The two methods can use delegation to pass the parameters directly to its internal property map representation. This protects the calling class from being coupled to the type of map used by the Node instance, allowing the map implementation itself to vary. (For example, perhaps later the Properties can be replaced with a more memory-efficient version, a faster map, or be provided a persistent properties map as a configuration option.) This doesn't affect the code in any way. One more item is the method name |
Good point. That also makes it shorter so 👍
I'm a bit confused about what you mean here. There isn't a |
That is the issue. The following lines contain duplicated code:
It's like writing:
This violates the Law of Demeter. (Sometimes playfully stated as, "You can play with yourself, you can play with your friends, but you can't play with your friends' friends.") This tightly couples knowledge of how Instead, drop in a few delegating methods that encapsulate the desired behaviour, rather than leaking it: public class Node {
private Properties getProperties() {
return this.properties;
}
/** Delegate to the internal properties map. */
public Object getProperty( final String key ) {
return getProperties().get( key );
}
public boolean setProperty( final String key, Object value ) {
getProperties().set( key, value );
}
public boolean hasProperty( final String key ) {
getProperties().contains( key );
// Or whatever...
}
} Then line 125, for example, becomes: return (Stack<InputMap<?>>) node.getProperty(P_STACK); Or, simplified even further: return node.getInputMapStack(); Now how the nodes store properties (and the input map stack) is an implementation detail that doesn't incur unnecessary coupling. |
I believe I understand the heart of what you are saying, which I understand as "code things differently so that, if the underlying implementation changes (say changing how a nodes' properties are stored from a Assuming I've understood you correctly, I am confused for a few reasons. First, I cannot add the desired The next best thing I could do is add additional methods to the public class Nodes {
// helper
private static Map<String, Object> getProperties(Node node) {
return node.getProperties();
}
private static Stack<InputMap<?>> getStack(Node node) {
return (Stack<InputMap<?>>) getMap(node).get(P_STACK);
}
// and similar methods for the other node.getProperties().get(P_[Input/Handler]) calls
// and then in other methods, I would only write `getStack(node);`
} Second, I don't see why the "possible change in implementation detail may cause coupling issues" is an issue (short of the code duplication which can be fixed with the code I mention in my first point). If the JavaFX |
Apologies -- I haven't been working with JavaFX for a few months now and did not look to see whether you had control over
The fixes you propose are excellent with respect to the JavaFX API design. The duplication is addressed and the Law of Demeter has been upheld as far as it can. |
Mm... That makes sense.
In that case, I'll push the changes and merge the PR. |
Closed by #18. |
The following code works as expected, but is coupled to the inner-workings of
Nodes.java
:An API for pushing and popping input maps would be helpful:
In this situation, a
StyleClassedTextArea
already has an input map and a number of key bindings. My code intercepts allkeyTyped()
andkeyPressed()
events untilEsc
is pressed, to offer the user an inline autocomplete-like mode. When the user pressesEsc
, the original input map for the editor should be restored. My code shouldn't need to maintain a reference to the editor's input map.The text was updated successfully, but these errors were encountered: