Question

I decided to dive a little bit deeeper in the materia of swing and custom painting components. The last few days I read tons of articles, API-documentations and questions here on StackOverFlow and other forums. But still I got some basic problems in understanding the concept.

What I want to do: Basically, I want to design some components for my own Swing GUI. I don't have much problems designing a custom JButton. I just create an custom Image in paint.net, create an ImageIcon and make JButton.setIcon(ImageIcon), that works fine. Same story if I want to customize the Thumb of a JSlider. I found a very funny solution here. It just overrides the default-thumb with nothing and in a second step it puts a custom ImageIcon (using my custom createImageIcon-class via ClassLoader) for the "Slider.horizontalThumbIcon" to the UIManger.

UIManager.getLookAndFeelDefaults().put("Slider.horizontalThumbIcon", new Icon(){

    public int getIconHeight() {
        return 0;
    }

    public int getIconWidth() {
        return 0;
    }

    public void paintIcon(Component c, Graphics g, int x, int y) {
       //do nothing
    }
});

and

UIManager.getLookAndFeelDefaults().put("Slider.horizontalThumbIcon", 
                                        createImageIcon("images/slider.png"));

But now the problem starts. If I'm not wrong, the thumb of a ScrollBar is not an Icon, so I have to create an own "CustomScrollBarUI"-class which extends BasicScrollBarUI. Further I don't wanted any arrow-keys. OK, so I did the following (inspiring me again from some sample code from here):

public class CustomScrollBarUI extends BasicScrollBarUI {

    private ImageIcon img;

    protected JButton createZeroButton() {
        JButton button = new JButton("zero button");
        Dimension zeroDim = new Dimension(0,0);
        button.setPreferredSize(zeroDim);
        button.setMinimumSize(zeroDim);
        button.setMaximumSize(zeroDim);
        return button;
    }


    protected JButton createDecreaseButton(int orientation) {
        return createZeroButton();
    }


    protected JButton createIncreaseButton(int orientation) {
        return createZeroButton();
    }


    protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
        BufferedImage img = new LoadBackgroundImage("images/slider.png").getImage();
        g.drawImage(img, 0, 0, new Color(255,255,255,0), null);
    }


    protected void setThumbBounds(int x, int y,int width,int height){
          super.setThumbBounds(x, y, 14, 14);
    }


    protected Rectangle getThumbBounds(){
          return new     Rectangle(super.getThumbBounds().x,super.getThumbBounds().y,14,14);
    } 


        protected Dimension getMinimumThumbSize(){
        return new Dimension(14,14);
    }


    protected Dimension getMaximumThumbSize(){
        return new Dimension(14,14);
    }
}

The LoadBackGroundImage is an own class, which creates a BufferedImage via ClassLoader. The thumb of the scrollbar is now my custom "slider.png", BUT it doesn't move. If I drag it down, the pane scrolls, but the thumb remains at his place. Due that I haven't understood all the mechanism yet, I read about the paintImage-method. There you have to commit an ImageObserver, whose function I don't really understand. I found various code examples on the net committing null (like I do), but i think this doesn't work for images that have to be moved (and so repainted). How can I solve this? If I paint a normal graphic in the paintThumb-method, it works fine, but as soon that I paint an Image, it doesn't move.

I'm hope somebody can help me. Thanks in advance.

Was it helpful?

Solution

In your specific case - you are always painting image @ the same location:

protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {
    BufferedImage img = new LoadBackgroundImage("images/slider.png").getImage();
    g.drawImage(img, 0, 0, new Color(255,255,255,0), null);
}

"0, 0" here is "x, y" coordinates in scroll bar coordinates system (which zero is placed in top left corner).

You recieve thumb bounds in paintThumb method (Rectangle thumbBounds) which points to current thumb location - just use those values to paint image on a proper place.

In case your thumb image size does not fit recieved thumbBounds you could calculate its middle point and center image at it. Thats just an example though - you can do it in any other way you like.

And i would like to add that almost every separated paint-method in various UI's are placed in the same coordinate system, so you always have to use recieved coordinates/bounds/... to place what you are painting OR calculate it on your own.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top