import javax.swing.*;
import javax.swing.plaf.basic.BasicScrollBarUI;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;

public class ScrollBarBug {
    private static JScrollBar sb;
    private static JFrame frame;
    static Point l;
    static Rectangle bounds;

    public static void main(String[] args) throws Exception {
        System.setProperty("sun.java2d.uiScale", "2.3");
        Robot robot = new Robot();
        SwingUtilities.invokeAndWait(()->test());
        robot.waitForIdle();
        robot.delay(1000);
        SwingUtilities.invokeAndWait(new Runnable() {
           public void run() {
              l = sb.getLocationOnScreen();
              System.out.println(l);
              bounds = sb.getBounds();
              System.out.println(bounds);
           }
        });
        robot.mouseMove(l.x + 30, l.y + 10);
        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
        glide(robot, l.x + 30, l.y + 10, l.x + 30 + bounds.width, l.y + 10);
        MultiResolutionImage mrImage = robot.createMultiResolutionScreenCapture(sb.getBounds());
        java.util.List<Image> variants = mrImage.getResolutionVariants();
        System.out.println(variants.size());
        Image image = variants.get(variants.size() - 1);
        javax.imageio.ImageIO.write((java.awt.image.RenderedImage) image, "png", new java.io.File("scrollbar-beforerelease.png"));
        robot.delay(1000);
        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
        mrImage = robot.createMultiResolutionScreenCapture(sb.getBounds());
        variants = mrImage.getResolutionVariants();
        System.out.println(variants.size());
        Image image1 = variants.get(variants.size() - 1);
        javax.imageio.ImageIO.write((java.awt.image.RenderedImage) image1, "png", new java.io.File("scrollbar-afterrelease.png"));
        compareImages((BufferedImage)image, (BufferedImage)image1);
    }

    private static void compareImages(BufferedImage i1, BufferedImage i2)
            throws Exception {
        final int MAXDIFFS = 10;
        int maxDiffs = MAXDIFFS;
        int diffCnt = 0;
        boolean failed = false;
        int width = i1.getWidth(null);
        int height = i1.getHeight(null);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if (maxDiffs == MAXDIFFS) {
                    int b1 = i1.getRGB(x, y) & 0x0ff;
                    int b2 = i2.getRGB(x, y) & 0x0ff;
                    /* If request to use AA_OFF is ignored,
                     * too hard, give up.
                     */
                    if ((b1 > 0 && b1 < 255) || (b2 > 0 && b2 < 255)) {
                        //System.out.println("AA text, skip.");
                        //return;
                    }
                }
                if (i1.getRGB(x, y) != i2.getRGB(x, y)) {
                    /* This is an attempt to mitigate against small
                     * differences, especially in the fractional metrics case.
                     */
                    diffCnt++;
                    if (diffCnt > maxDiffs) {
                        failed = true;
                    }
                }
            }
        }
        System.out.println("diffCnt = " + diffCnt);
        if (failed) {
            throw new RuntimeException("images differ diffCnt=" + diffCnt);
        }
    }

    public static void glide(Robot robot, int x0, int y0, int x1, int y1) {
        System.out.println("x0 " + x0 + " x1 " + x1);
        int dmax = x1 - x0;
        for (int i = 0; i <= dmax; i += 10) {
            robot.mouseMove((int) (x0 + 5 * i), y1);
            robot.delay(1000);
            System.out.println(i);
            System.out.println(sb.getValue());
            if (sb.getValue() + sb.getModel().getExtent() >= sb.getMaximum()) {
                break;
            }
        }
    }
    public static void test() {
        JFrame f = new JFrame();
        JPanel panel = new JPanel(new BorderLayout());
        sb = new JScrollBar(JScrollBar.HORIZONTAL);
        DefaultBoundedRangeModel rangeModel = new DefaultBoundedRangeModel();
        rangeModel.setMaximum(100);
        rangeModel.setMinimum(0);
        rangeModel.setExtent(10);
        rangeModel.setValue(0);
        sb.setModel(rangeModel);
        panel.add(sb, "South");
        f.setContentPane(panel);
        f.setSize(800, 200);
        f.setVisible(true);
    }
}