JDK-8136346 : [TextFlow] Expose API to obtain caret and selection shapes
  • Type: Sub-task
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-09-11
  • Updated: 2016-03-14
  • Resolved: 2016-03-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
This is related to JDK-8092278 and JDK-8130362, but asks for much less. While those tickets ask for selection/cut/copy/paste functionality to be implemented by TextFlow, here I want to ask to only expose low-level methods to obtain the selection/caret shape (for a given range/position).

This is all it takes to implement those methods in TextFlow.java (see also the attached patch against 9-dev):

    public PathElement[] getCaretShape(int charIdx, boolean isLeading) {
        return getTextLayout().getCaretShape(charIdx, isLeading, 0.0f, 0.0f);
    }

    public PathElement[] getSelectionShape(int from, int to) {
        return getTextLayout().getRange(from, to, TextLayout.TYPE_TEXT, 0, 0);
    }

This, together with a hit-test API (JDK-8090357, JDK-8091012) allows users to implement such higher level functionality as selection, copy&paste, editing...

I have implemented the equivalents of the above methods in RichTextFX using reflection and com.sun.javafx.scene.text.TextLayout, and implemented selection and editing on top of them. This request is prompted by the fact that starting with JDK 9, com.sun.* APIs will not be accessible.

My hope is that this could be targeted for 9.
Comments
I used the name TextPosInfo in the skin instead of HitInfo to make it clear that it can be used for creating an general info object, and not just for doing a hit test. I think we can move TextPosInfo to javafx.scene.text and remove HitInfo from com.sun.ditto.
22-09-2015

Yes, using the HitInfo/TextPosInfo makes sense to me. Though it should still be possible to obtain caret shape without first doing a hit test.
22-09-2015

I think that makes sense. One thing to keep in mind is to make it work correctly with character clusters (JDK-8092327).
22-09-2015

Maybe the caret position parameter should use HitInfo as proposed in JDK-8136350.
22-09-2015

Agreed. If the methods don't use the internal state, then users of the API don't have to keep moving the caret or selection just to get some coordinates. The proposed patch seems simple enough. Should we expand this request to cover both Text and TextFlow, then?
22-09-2015

The existing impl_* methods for caret and selection shape of Text require Text to also keep track of the current caret position and selection range itself (which I'm not sure is a good idea). To do that, they require presence of additional methods for setting and getting caret position and selection range (also currently present as impl_* methods), which would have to be made public as well. The API proposed here is more basic (doesn't require the Text itself to keep track of caret position and selection range) and more universal - the current impl_* methods can be implemented on top of the methods proposed here, but not vice versa. As a use case for this more basic version, getting the selection shape of certain range without affecting Text's internally stored selection range is used in RichTextFX to implement background color support for Text inside TextFlow. I am more in favor of supporting basic features on which more complex features can be built. Note that the impl_* methods on Text don't work well for Text inside TextFlow (see JDK-8119007, which has been marked as incomplete only because impl_* is private API). Anyway, implementing this API for TextFlow would eliminate the need to call the corresponding API on Text inside TextFlow.
22-09-2015

This has been a requested API since the FX Script days. The methods already exist as public but deprecated impl_* API in the Text class. Maybe it's just a matter of renaming them and supporting them officially?
22-09-2015

Not exposing such API keeps JavaFX controls privileged, i.e. controls shipped with JavaFX could not be implemented in user-space. I think it is important to empower authors of custom controls by giving them all the power that built-in controls have access to. Because, what Oracle doesn't have the bandwidth to do in the first place, is to provide all the controls the users could possibly want. (I strongly believe adding basic features is much more important than, for example, making the built-in skins public - those will always be just skins for the same old controls, thus their usefulness is by definition limited. Plus customization by inheritance is limited. Plus the current use cases it is supposed to rescue are dubious anyway (see http://mail.openjdk.java.net/pipermail/openjfx-dev/2015-September/017848.html). I am amazed by the amount of questionable API being uncritically dumped into public, and at the same time reluctance (see how old the related issues are) to add basic features.)
22-09-2015

I doubt we have the bandwidth to do any more unscheduled public API work for 9. Lief or Kevin, what is your take?
22-09-2015