Fix #712: guard against zero/negative plot area in Plot_AxesChart#974
Merged
timmolter merged 2 commits intoJun 19, 2026
Merged
Conversation
When the chart window is resized to be very narrow (especially with multiple Y-axis groups), axis columns can consume more space than the total chart width, leaving zero or negative dimensions for the plot area. Painting with degenerate geometry caused a NullPointerException in AWT path operations inside PlotContent_XY.doPaint(). Add an early-exit guard in Plot_AxesChart.paint() that assigns a zero-size Rectangle2D and returns immediately when the computed plot width or height is <= 0. This preserves a non-null getBounds() for downstream components (e.g. Legend_) while skipping all rendering. The existing guard in PlotContent_.paint() (width < 30) handles the near-zero case for individual plot-content renderers, but is insufficient when geometry goes fully non-positive at the Plot level. Adds two regression tests and a TestForIssue712 demo class. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes #712 by preventing axes-based charts from attempting to paint when computed plot bounds become non-positive (e.g., extremely narrow XChartPanel with multiple Y-axis groups), which previously could trigger repeated NullPointerExceptions during rendering.
Changes:
- Add an early-exit guard in
Plot_AxesChart.paint()when plotwidth <= 0orheight <= 0, while still assigning a non-null bounds rectangle. - Add regression tests to ensure painting very small XY charts (including multiple Y-axis groups) does not throw.
- Add a standalone demo (
TestForIssue712) to reproduce/validate the narrow-resize scenario interactively.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| xchart/src/main/java/org/knowm/xchart/internal/chartpart/Plot_AxesChart.java | Adds guard against zero/negative plot bounds to avoid downstream renderer failures. |
| xchart/src/test/java/org/knowm/xchart/XYChartTest.java | Adds regression coverage for painting 1×1 charts (single and multi Y-axis groups). |
| xchart-demo/src/main/java/org/knowm/xchart/standalone/issues/TestForIssue712.java | Adds a runnable demo to manually verify no exception when resizing extremely narrow. |
…rly exit When the plot area is zero/negative, the early return in Plot_AxesChart.paint() now also clears the plot content's interactionData (if active) and resets its plotBounds to the zero-size rectangle. This prevents stale tooltip/cursor overlays from persisting after the window is shrunk too small to render. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When a
XChartPanelis resized to be very narrow — especially with multiple Y-axis groups — each axis column consumes horizontal space. Once the total axis width exceeds the chart width, the remaining plot area becomes zero or negative. Painting with that degenerate geometry caused a repeatingNullPointerExceptiondeep insidePlotContent_XY.doPaint().Fixes #712.
Root Cause
Plot_AxesChart.paint()computedwidth = xAxisBounds.getWidth()andheight = yAxisBounds.getHeight()and passed them straight tonew Rectangle2D.Double(...). Whenwidth <= 0orheight <= 0, every downstream renderer (PlotContent_XY,Legend_, etc.) received a rectangle with invalid dimensions, causing NPEs in AWT path operations.The existing guard in
PlotContent_.paint()(bounds.getWidth() < 30) handles near-zero cases but is insufficient when the bounds goes fully non-positive at thePlot_AxesChartlevel.Fix
Added an early-exit guard in
Plot_AxesChart.paint():A zero-size
Rectangle2Dis still assigned so downstream callers likeLegend_.paint()(which readschart.getPlot().getBounds()) always receive a non-null value;Legend_'s own existingwidth < 30check then correctly skips painting.Testing
paintingTinyChartDoesNotThrow()— paints a 1×1 chartpaintingTinyChartWithMultipleYAxisGroupsDoesNotThrow()— paints a 1×1 chart with 3 Y-axis groups (the original failure scenario)TestForIssue712.javademo — run and resize the window as narrow as possible to verify no exception is thrownxcharttest suite passes (mvn test -pl xchart)