Skip to content
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

(Theming) Inconsistent highlighting for long JTables #441

Open
goodwilling opened this issue Jan 9, 2023 · 21 comments
Open

(Theming) Inconsistent highlighting for long JTables #441

goodwilling opened this issue Jan 9, 2023 · 21 comments

Comments

@goodwilling
Copy link

Version of Radiance (latest release is 7.0-SNAPSHOT)

7.0-SNAPSHOT

Sub-project (Common, Animation, Theming, Component, ...)

Theming

Version of Java (current minimum is 9)

Java 17

Version of OS

RHEL 8.4 and RHEL 9.0

The issue you're experiencing (expected vs actual, screenshot, stack trace etc)

The highlighting for rows of a long JTable becomes inconsistent and unstable, as shown by the attached snapshot. The problems have not been reproduced on Windows 10. Also, the problems have not been reproduced on RHEL 8/9 with the Radiance-theming version of Jan-2022.
highlight-problems

@kirill-grouchnikov
Copy link
Owner

I'm not sure what I'm looking at.

What is a long table? A lot of columns with horizontal scrolling, or a lot of rows with vertical scrolling?
Am I seeing four separate screenshots here?
Is that grey artifact (vertical bar "connected" to the horizontal bar) the issue you are referring to?
What is being highlighted here, rows or columns or individual cells?

Is this reproducible in the main Radiance demo in org.pushingpixels.radiance.demo.theming.main.Check? In its Table tab you can add up to 10K rows.

@goodwilling
Copy link
Author

Sorry for my poor description above. The table is a table with a lot of rows with vertical scrolling. There are four sceenshots in different look-and-feels. The problem is that the grey artifacts (or different colors) come out in the column.

I have not tried the main Radiance demo yet.

@kirill-grouchnikov
Copy link
Owner

Is it also the issue with that partial color displayed under -26. part of -26.19... in the second column of the first and third screenshots?

My primary suspect would be that it has something to do with the major refactoring of the rendering pipeline that was done last year. There was one issue that was fixed in 5c62668 for 6.5.0, but other than that, I'm not seeing anything else in the demo.

Note that I do not have access to the particular environment (RHEL), so if it only happens there, I won't be able to debug this issue.

@goodwilling
Copy link
Author

Yes, it is also the issue with that partial color displayed under -26. part of -26.19... in the second column of the first and third screenshots, and this issue comes out most frequently. The grey artifact does not come out so often but can be reproduced.

I have tried other environments, and this problem can be reproduced in Rocky Linux 8.4, but not seen in RHEL 7.

@kirill-grouchnikov
Copy link
Owner

Are you using different screens, or same screen? Most of the issues that were fixed in the new rendering pipeline were only reproducible on regular-resolution / low-DPI screens.

@goodwilling
Copy link
Author

I am using virtual machines (Virtualbox 7.0) for the Linux systems, in the same Windows host.

@kirill-grouchnikov
Copy link
Owner

In terms of trying to pinpoint the issue on your system, since I don't have access to these environments:

  1. The highlights are drawn in RadianceTableUI in the HighlightPainterUtils.paintHighlight calls.
  2. Lines 1047 and 1065 are for the currently edited cell - so not relevant
  3. Line 1101 is for the current drop location - so not relevant
  4. Lines 1101 and 1126 are relevant
  5. Comment them out and see if this is still an issue
  6. If commenting them out removes the issue, then it's in HighlightPainterUtils
  7. Comment out line 95 that draws the highlight fill
  8. Comment out line 97 that draws the highlight border

Sorry for dropping this on your side, but that's pretty much all I can do without a reproducer on my side on either Windows or macOS

@goodwilling
Copy link
Author

I have tried to comment out Lines 1101 and 1126 in theming/src/main/java/org/pushingpixels/radiance/theming/internal/ui/RadianceTableUI.java:

                RadianceColorScheme borderScheme = RadianceColorSchemeUtilities
                        .getColorScheme(table, RadianceThemingSlices.ColorSchemeAssociationKind.HIGHLIGHT_BORDER,
                                currState);
                float extra = RadianceSizeUtils.getBorderStrokeWidth(table);
                //HighlightPainterUtils.paintHighlight(g2d, this.rendererPane, rendererComponent,
                //        new Rectangle(highlightCellRect.x - (int) extra,
                //                highlightCellRect.y - (int) extra,
                //                highlightCellRect.width + (int) extra,
                //                highlightCellRect.height + (int) extra),
                //        0.8f, null, scheme, borderScheme);
            } else {
                float extra = RadianceSizeUtils.getBorderStrokeWidth(table);
                float extraWidth = highlightOpenSides.contains(RadianceThemingSlices.Side.LEFT) ? 0.0f
                        : extra;
                float extraHeight = highlightOpenSides.contains(RadianceThemingSlices.Side.TOP) ? 0.0f
                        : extra;
                Rectangle highlightRect = new Rectangle(highlightCellRect.x - (int) extraWidth,
                        highlightCellRect.y - (int) extraHeight,
                        highlightCellRect.width + (int) extraWidth,
                        highlightCellRect.height + (int) extraHeight);
                if (activeStates == null) {
                    RadianceColorScheme fillScheme = this.updateInfo
                            .getHighlightColorScheme(currState);
                    RadianceColorScheme borderScheme = this.updateInfo
                            .getHighlightBorderColorScheme(currState);
                    float alpha = this.updateInfo.getHighlightAlpha(currState);
                    if (alpha > 0.0f) {
                        g2d.setComposite(
                                WidgetUtilities.getAlphaComposite(this.table, alpha, g));
                        //HighlightPainterUtils.paintHighlight(g2d, this.rendererPane,
                        //        rendererComponent, highlightRect, highlightBorderAlpha,
                        //        highlightOpenSides, fillScheme, borderScheme);
                        //g2d.setComposite(WidgetUtilities.getAlphaComposite(this.table, g));
                    }
                } else {
                ...

but things do not change. When I click the columns and move the mouse, I can get the screenshot as attached.
highlight-problems

@kirill-grouchnikov
Copy link
Owner

Sorry my bad. 1126 and 1144 are relevant here. 1101 is for drawing the highlights for the current drop location

@goodwilling
Copy link
Author

Sorry. I made a mistake to comment out
g2d.setComposite(WidgetUtilities.getAlphaComposite(this.table, g));

After commenting out 1126 and 1144, the highlighting problem disappears!

                if (activeStates == null) {
                    RadianceColorScheme fillScheme = this.updateInfo
                            .getHighlightColorScheme(currState);
                    RadianceColorScheme borderScheme = this.updateInfo
                            .getHighlightBorderColorScheme(currState);
                    float alpha = this.updateInfo.getHighlightAlpha(currState);
                    if (alpha > 0.0f) {
                        g2d.setComposite(
                                WidgetUtilities.getAlphaComposite(this.table, alpha, g));
                        //HighlightPainterUtils.paintHighlight(g2d, this.rendererPane,
                        //        rendererComponent, highlightRect, highlightBorderAlpha,
                        //        highlightOpenSides, fillScheme, borderScheme);
                        g2d.setComposite(WidgetUtilities.getAlphaComposite(this.table, g));
                    }
                } else {
                    for (Map.Entry<ComponentState, StateTransitionTracker.StateContributionInfo> stateEntry : activeStates
                            .entrySet()) {
                        ComponentState activeState = stateEntry.getKey();
                        RadianceColorScheme fillScheme = this.updateInfo
                                .getHighlightColorScheme(activeState);
                        RadianceColorScheme borderScheme = this.updateInfo
                                .getHighlightBorderColorScheme(activeState);
                        float alpha = this.updateInfo.getHighlightAlpha(activeState)
                                * stateEntry.getValue().getContribution();
                        if (alpha > 0.0f) {
                            g2d.setComposite(
                                    WidgetUtilities.getAlphaComposite(this.table, alpha, g));
                            //HighlightPainterUtils.paintHighlight(g2d, this.rendererPane,
                            //        rendererComponent, highlightRect, highlightBorderAlpha,
                            //        highlightOpenSides, fillScheme, borderScheme);
                            g2d.setComposite(WidgetUtilities.getAlphaComposite(this.table, g));
                        }
                    }

@kirill-grouchnikov
Copy link
Owner

So now it will be this part:

  1. If commenting them out removes the issue, then it's in HighlightPainterUtils
  2. Comment out line 95 that draws the highlight fill
  3. Comment out line 97 that draws the highlight border

@goodwilling
Copy link
Author

・Without commenting out 1126 and 1144 in RadianceTableUI, either commenting out line 95 or line 97 in HighlightPainterUtils can solve the highlighting issue. However, the header of the table looks strangle (the fonts become ugly) in either case.

・Commenting out both line 95 and line 97 makes the issue come out again when clicking the columns.

・Commenting out 1126 and 1144 in RadianceTabeleUI seems to remove the issue if just moving the mouse, however,
the issue comes out again when clicking the columns. Sorry for the previous report.

@kirill-grouchnikov
Copy link
Owner

8d7aaf1 is a very small fix in HighlightPainterUtils. I don't think it's likely to address the issue you're seeing, but wouldn't hurt to try.

To your points:

  1. What does it mean that the fonts are ugly? Does it lose the anti-aliasing compared to the rest of the table?
  2. Commenting out the lines highlightPainter.paintContourBackground and paintHighlightBorder1X should remove all the background / border highlights and only leave changes to the text. Are you seeing the yellow highlights still painted?
  3. Same as 2. Clicking a column makes the cells selected, but removing the highlight drawing should remove the yellow background fill.

What are you seeing in 2 and 3, if you can attach screenshots?

@kirill-grouchnikov
Copy link
Owner

The next step would be to replace calls to Radiance fill / border painters with something that just uses direct Java2D APIs:

    private static void paintHighlight(Graphics g, Component c, Rectangle rect,
            float borderAlpha, Set<RadianceThemingSlices.Side> openSides,
            RadianceColorScheme fillScheme, RadianceColorScheme borderScheme,
            RadianceFillPainter highlightPainter,
            RadianceBorderPainter highlightBorderPainter) {
        Graphics2D g2d = (Graphics2D) g.create();

        g2d.setColor(Color.red);
        g2d.fill(rect);

        g2d.translate(rect.x, rect.y);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        RadianceCommonCortex.paintAtScale1x(g2d, 0, 0, rect.width, rect.height,
                (graphics1X, x, y, scaledWidth, scaledHeight, scaleFactor) -> {
                    Path2D result = new Path2D.Float();
                    result.moveTo(0.0f, 0.0f);
                    result.lineTo(scaledWidth - 1.0f, 0.0f);
                    result.lineTo(scaledWidth - 1.0f, scaledHeight - 1.0f);
                    result.lineTo(0.0f, scaledHeight - 1.0f);
                    result.lineTo(0.0f, 0.0f);
                    g2d.setColor(Color.blue);

                    g2d.draw(result);
                });

        g2d.dispose();
    }

With this you should see bright red highlights with pixel-thing blue borders

@kirill-grouchnikov
Copy link
Owner

Small correction to use the right graphics context:

    private static void paintHighlight(Graphics g, Component c, Rectangle rect,
            float borderAlpha, Set<RadianceThemingSlices.Side> openSides,
            RadianceColorScheme fillScheme, RadianceColorScheme borderScheme,
            RadianceFillPainter highlightPainter,
            RadianceBorderPainter highlightBorderPainter) {
        Graphics2D g2d = (Graphics2D) g.create();

        g2d.setColor(Color.red);
        g2d.fill(rect);

        g2d.translate(rect.x, rect.y);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        RadianceCommonCortex.paintAtScale1x(g2d, 0, 0, rect.width, rect.height,
                (graphics1X, x, y, scaledWidth, scaledHeight, scaleFactor) -> {
                    Path2D result = new Path2D.Float();
                    result.moveTo(0.0f, 0.0f);
                    result.lineTo(scaledWidth - 1.0f, 0.0f);
                    result.lineTo(scaledWidth - 1.0f, scaledHeight - 1.0f);
                    result.lineTo(0.0f, scaledHeight - 1.0f);
                    result.lineTo(0.0f, 0.0f);
                    graphics1X.setColor(Color.blue);

                    graphics1X.draw(result);
                });

        g2d.dispose();
    }

@goodwilling
Copy link
Author

8d7aaf1 is a very small fix in HighlightPainterUtils. I don't think it's likely to address the issue you're seeing, but wouldn't hurt to try.

  1. What does it mean that the fonts are ugly? Does it lose the anti-aliasing compared to the rest of the table?
  2. Commenting out the lines highlightPainter.paintContourBackground and paintHighlightBorder1X should remove all the background / border highlights and only leave changes to the text. Are you seeing the yellow highlights still painted?
  3. Same as 2. Clicking a column makes the cells selected, but removing the highlight drawing should remove the yellow background fill.

What are you seeing in 2 and 3, if you can attach screenshots?

I have redone the tests and it was found that "gradle build" after "gradle clean" of previously-built radiance is necesary, otherwise the test results depend on how the radiance library is built. The following are my test results.

8d7aaf1 did not fix the highlighting issue. By the way, it is found that there exists a "border row" beyond which the highlighting issue comes out. For example, beyond the row 1638 in the attached snapshot (1st one), the issue comes out.

Commenting out the lines highlightPainter.paintContourBackground remove all the background highlights and only leave changes to the text. The fonts in the header become ugly (lose the anti-aliasing compared to the rest of the table). Moreover, moving the horizontal slide bar left and right makes that the header of the table can not be updated correctly.

Commenting out paintHighlightBorder1X seems to be different but the issue is still there. Moving the horizontal slide bar left and right results in some updating issues in the column.

highlight-problems

@goodwilling
Copy link
Author

Small correction to use the right graphics context:

    private static void paintHighlight(Graphics g, Component c, Rectangle rect,
            float borderAlpha, Set<RadianceThemingSlices.Side> openSides,
            RadianceColorScheme fillScheme, RadianceColorScheme borderScheme,
            RadianceFillPainter highlightPainter,
            RadianceBorderPainter highlightBorderPainter) {
        Graphics2D g2d = (Graphics2D) g.create();

        g2d.setColor(Color.red);
        g2d.fill(rect);

        g2d.translate(rect.x, rect.y);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        RadianceCommonCortex.paintAtScale1x(g2d, 0, 0, rect.width, rect.height,
                (graphics1X, x, y, scaledWidth, scaledHeight, scaleFactor) -> {
                    Path2D result = new Path2D.Float();
                    result.moveTo(0.0f, 0.0f);
                    result.lineTo(scaledWidth - 1.0f, 0.0f);
                    result.lineTo(scaledWidth - 1.0f, scaledHeight - 1.0f);
                    result.lineTo(0.0f, scaledHeight - 1.0f);
                    result.lineTo(0.0f, 0.0f);
                    graphics1X.setColor(Color.blue);

                    graphics1X.draw(result);
                });

        g2d.dispose();
    }

Applying this correction fix the highlighting issue (the highlighting color is red as set). Thanks. (Side effect?) moving the horizontal slide bar left and right makes the header of the table can not be updated correctly (some vertical blue lines are seen in the header).
highlight-problems

@kirill-grouchnikov
Copy link
Owner

Thanks. So it is a combination of the specific OS version + a specific Java version, or all Java versions on that OS?

@goodwilling
Copy link
Author

The side effect that moving the horizontal slide bar left and right makes the header of the table incorrectly updated with some vertical blue lines is not dependent on OS and Java. It can be reproduced in all versions of RedHat, and also Windows 10, with either Java 11 or Java 17.

@kirill-grouchnikov
Copy link
Owner

I'm not sure how to proceed here, to be honest. Looks like the issue is somewhere in HighlightPainterUtils.paintHighlightBorder1X and its usage of HiDPIUtils.paintAtScale1x that applies a scale-based affine transform on the graphics context to draw pixel-wide borders.

My next step if I could reproduce this locally would be to start looking at the various pieces in HiDPIUtils.paintAtScale1x, extracting them one by one into the sample paintHighlight implementation from my earlier comment until I find the problematic line. But I'm not seeing this on my macOS. Will try that sample highlight on my Windows 10 machine a bit later.

@kirill-grouchnikov
Copy link
Owner

Can't reproduce this on my Windows 10 with Oracle OpenJDK 17.0.2 either. I have a high DPI screen at 2.5x scale factor, and forcing 1x in code doesn't show any issue either. I did notice though that both RadianceTableUI.paintGrid and RadianceTableHeaderUI.paintGrid are not using the new rendering pipeline. I'll convert both of them tomorrow. This is unlikely to address the highlight grey rectangles in the table, and might not affect the table header as well - since it looks like you're only seeing it on selected columns, and these methods are for unselected ones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants