Java Graphics and Bordering Problems in JScrollPane

174 views Asked by At

I have found a CustomScrollbarUIExample, and I am trying to change it completely into my own (with attribution, of course, this is legal). I have immediately run into a problem.

What I am trying to achieve is put a border around not the JScrollPane itself, but the moveable block if you understand what I meen.

I have put the modified source code below, and I have highlighted my problem.

package com.finn.chess;

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.plaf.metal.MetalScrollBarUI;

/** @see https://stackoverflow.com/a/12270067/230513 */
public class CustomScrollbarUIExample {

public static void main(String[] args) {
    JScrollPane before = makeExamplePane();
    JScrollPane after = makeExamplePane();
    after.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    JScrollBar sb = after.getVerticalScrollBar();
    sb.setUI(new MyScrollbarUI());
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setLayout(new GridLayout(0,1));
    f.add(before);
    f.add(after);
    f.pack();
    f.setSize(320, 240);
    f.setVisible(true);
}

private static JScrollPane makeExamplePane() {
    JTextArea text = new JTextArea(16, 16);
    text.append("Lorem ipsum dolor sit amet…");
    JScrollPane scroll = new JScrollPane(text);
    return scroll;
}

static class MyScrollbarUI extends MetalScrollBarUI {

    private Image imageThumb, imageTrack;
    private JButton b = new JButton() {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(0, 0);
        }

    };

    MyScrollbarUI() {
        imageThumb = FauxImage.create(32, 32, Color.blue.brighter());
        imageTrack = FauxImage.create(32, 32, Color.BLACK);
    }

    @Override
    protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
        g.setColor(Color.blue);
        ((Graphics2D) g).drawImage(imageThumb,
            r.x, r.y, r.width, r.height, null);
    }

    @Override
    protected void paintTrack(Graphics g, JComponent c, Rectangle r) {
        ((Graphics2D) g).drawImage(imageTrack,
            r.x, r.y, r.width, r.height, null);
    }

    @Override
    protected JButton createDecreaseButton(int orientation) {
        return b;
    }

    @Override
    protected JButton createIncreaseButton(int orientation) {
        return b;
    }
}

private static class FauxImage {

    static public Image create(int w, int h, Color c) {
        BufferedImage bi = new BufferedImage(
            w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = bi.createGraphics();
        g2d.setPaint(c);
        g2d.fillRect(0, 0, w, h);
        
        // THIS IS MY PROBLEM, THE BORDER
        g2d.setPaint(Color.WHITE);
        g2d.drawRect(0, 0, w-1, h-1);
        
        g2d.dispose();
        return bi;
    }
}
}

Just at the end, you can see that I setup a border to put around it. But in big sizes, it appears like this:

Scroll bar

I don't want that massive block of white down the bottom; I want a simple, one pixel high border. How do I achieve this? Also I am posting a brand new thread because the other one was 2 years old, and I can't add ALL this into a comment.

1

There are 1 answers

4
trashgod On BEST ANSWER

Add the border in paintThumb(), after the image has been scaled by drawImage(). Starting from the original and using Color.red for emphasis, the result is seen below:

image

@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
    g.setColor(Color.blue);
    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(imageThumb, r.x, r.y, r.width, r.height, null);
    g2d.setPaint(Color.red);
    g2d.drawRect(r.x, r.y, r.width - 1, r.height);
}