Code that exists only because something upstream (JavaFX, a library, a tool) does not do what it should or could.
Each entry says where the workaround lives, what upstream does, which upstream issue tracks it, and how to tell that it can go.
In code, every workaround carries a Workaround W<n> marker naming its entry here, so git grep "Workaround W3" finds all of it; scripts/consistency.sh checks that markers and entries match.
What to report upstream — these bugs, others without a workaround, and feature requests — is collected in upstream.md.
When upstream fixes one: remove the code at every marker, delete the entry (the number is not reused), and note it in CHANGELOG.md if behavior changes.
- W1 —
TextAreadoes not size itself to its content (JDK-8091714, JDK-8181766):MessageTextmeasured its text. Gone 2026-09-22 with theTextAreabodies; a bubble body is aRichTextAreawithuseContentHeightnow (W5 is the narrower remainder). - W2 —
TextArea's innerScrollPaneswallowed wheel events:BubbleViewredirected them to the list. Gone 2026-09-22 with theTextAreabodies: a content-highRichTextAreapasses wheel events on (WheelOverBodyUiTestpasses without the filter).
- Where:
chatpane.css, rules.chat-pane .chat-pane-transcript .message-textand.chat-pane .message-bubble .message-text(-fx-fill). - Upstream: a segment added with
RichParagraph.Builder.addWithStyleNamesis not aTextcarrying those names: the area resolves the names through the stylesheet into styles and draws a plainTextwith them (seen in the node tree: the shownTexthas no style class). The area's own-fx-text-fill(Modena:-fx-text-inner-color) reaches no segment — a standalone check (2026-09-22) showed a plain segment and a style-named one both black under.rich-text-area { -fx-text-fill: red }— so without an explicit-fx-fillthe text stays black, unreadable in a dark theme. Consequence for tests: find shown segments by their text, not by style class. No upstream issue found;jfx.incubator.richtext(26.0.2) is an incubator module, tracked in general by JDK-8351982. - Removable when: transcript and bubble text read light in the demo's dark theme (
just demo --layout=irc --theme=dark) with the-fx-fillrules removed.
- Where: the
[impl->dsn~chatpane-stylesheet~…]tag sits onChatPane.getUserAgentStylesheetinstead of inchatpane.css. - Upstream: OpenFastTrace's tag importer has no
.cssfile type. No upstream issue filed. - Removable when: OpenFastTrace imports tags from
.cssfiles; then the tag moves into the stylesheet's header comment.
- Where:
BubbleText(computePrefWidthand the measuringGroupofTexts the cell puts into the bubble). - Upstream:
useContentWidthmakes the preferred width the content width but stops wrapping — a long message becomes one cut-off line (probe 2026-09-22: preferred 694 px, shown 336 px, one line); without it, a short message gets a full-width bubble. The body therefore measures its widest line itself, withTextnodes that carry the spans' style names inside the bubble, so the stylesheet gives them the fonts the area's text gets. No upstream issue found; related: JDK-8310593 (useContentWidth/Height for scrollable controls), JDK-8344643 (RichTextArea). - Removable when: a
RichTextAreaoffers "preferred width = widest line, wrap below the max width"; thenBubbleTextsets it and drops its measuring. Check:BubbleTextUiTest.bodyIsAsTallAsItsTextAndShrinksToShortText.
- Where:
TranscriptViewandBubbleTextsetwrapText,useContentHeight,displayCaretandhighlightCurrentParagraphin code;chatpane.cssno longer sets them. - Upstream: with
-fx-wrap-textcoming from the pane's user-agent stylesheet, adding a stylesheet to the scene (the demo's dark theme) re-applies CSS, the property changes in the middle of that pass, and the area'sVFlow.handleWrapTextlays out right away:IllegalArgumentException: Children: duplicate children added: parent = Pane[styleClass=content]fromVFlow.prepareCell(Carl, 2026-09-22;TranscriptStylingUiTestreproduced it). A standalone check with the wrapping in an author stylesheet did not fail, so the trigger needs the property to change during the pass. No upstream issue found; tracked in general by JDK-8351982. - Removable when: the settings move back into
chatpane.css(so applications can style them) andTranscriptStylingUiTestpasses, with no exception on the FX thread.
- Where:
StyleProbeinChatPaneSkin(styled from every lookup the text uses, inchatpane.css) andConversationView.restyle()— the transcript callsRichTextAreaSkin.refreshLayout(), bubbles rebuild their cells. - Upstream: the area turns a segment's style names into styles when it builds the text cell (
VFlow.resolveStylesmeasures a probeText) and keeps the cell. A later CSS change — another theme, a stylesheet added — does not reach built cells (standalone check: a segment namedtintedstayed red after the stylesheet switched.tintedto blue), and cells built before the pane's CSS was in place keep the defaults (Carl, 2026-09-22: the transcript "shows initially without styling" until the renderer is switched, which builds a new model). No upstream issue found. - Removable when: the area re-resolves styles on CSS changes itself; check:
TranscriptStylingUiTestpasses with the probe's callback doing nothing.
- Where:
BubbleText.computePrefHeight. - Upstream: with
useContentHeight, the area's preferred height comes from the arrangement itsVFlowbuilds inlayoutChildren; before that first layout it reportsParams.LAYOUT_MIN_HEIGHTplus insets (26 px in the probe), and once laid out it sets its preferred height and asks for another layout — a pulse later. The bubble list measures a fresh cell before its body ever laid out, and a growing answer builds its cell anew with every word: the newest bubble shrank to one line for a frame and grew back (66 px), so the whole list jumped by the difference with every word (Carl, 2026-10-05: "the scroll jumps crazy"). The body therefore lays itself out at its preferred width within the bubble before it reports its height — the width is-1there, the area has no content bias. No upstream issue found; related: JDK-8310593 (useContentWidth/Height for scrollable controls). - Removable when: a fresh
RichTextAreawithuseContentHeightreports its content height before its first layout; then the override goes. Check:FollowNewestUiTest.bubblesDoNotShrinkWhileTheNewestGrows.
- Where:
TranscriptView.removed. - Upstream: the selection model holds its caret as a model marker; an edit above the caret shifts the marker, the area sees a selection change, and
VFlow.handleSelectionChangecallsscrollCaretToVisible()— as if the user had moved the caret. Following the newest message parks the hidden caret at the end of the transcript, so deleting any message the user looks at scrolled the view to the end (Carl, 2026-10-05: "in irc and modern it still jumps to the end on delete"). Without a selection, the view therefore clears the caret before it removes; the next follow puts it back. No upstream issue found. - Removable when: a caret moved only by a model edit no longer scrolls the area; then
removedstops clearing it. Check:FollowNewestUiTest.transcriptStaysWhenAMessageIsDeletedwith theclearSelection()call removed.