Search code examples
javauser-interfaceswinglook-and-feelsynth

Controlling layout of a checkbox in a custom Synth Look & Feel


I'm trying to implement a custom "Steampunk" themed look and feel using Synth - basically providing custom versions of SynthStyle, SynthPainter and SynthStyleFactory.

I am not using any XML, i.e. everything is done through the Java API. In general this is working just fine and actually starting to look pretty decent.

However I am having trouble with some "composite" components such as JCheckBox. When the paintCheckBoxBackground() is called on the SynthPainter the coordinates refer to the whole area covered by the JCheckBox.

How should I determine where in this region the check box icon and text separately need to be drawn?


Solution

  • Well, mb the following will help (the code is to put into your custom painter associated with JCheckBox):

    public void paintCheckBoxBackground(SynthContext context, Graphics g, int x, int y, int w, int h){
    
        AbstractButton c = (AbstractButton) context.getComponent();
        String text = c.getText();
        Icon icon = c.getIcon();
        if (icon == null){
            icon = context.getStyle().getIcon(context, "CheckBox.icon");
        };        
        int iconTextGap = c.getIconTextGap();       
    
        Rectangle componentRect = new Rectangle();
        Rectangle iconR = new Rectangle();
    
        Insets insets = new Insets(0, 0, 0, 0);
        if (context.getRegion().isSubregion()){
            insets = context.getStyle().getInsets(context, insets);
        }
        else{
            insets = context.getComponent().getInsets(insets);
        }
    
        componentRect.x = insets.left;
        componentRect.y = insets.top;
        componentRect.width = c.getWidth() - (insets.left + insets.right);
        componentRect.height = c.getHeight() - (insets.top + insets.bottom);
    
        if (icon != null){
            iconR.x += componentRect.x;
            iconR.y += componentRect.y;
            iconR.width = icon.getIconWidth();
            iconR.height = icon.getIconHeight();
    
            g.setColor(Color.GREEN);
            g.fillRect(iconR.x, iconR.y, iconR.width, iconR.height);
        }
        if (text != null){
            g.setColor(Color.RED);
            int textPos = iconR.x + iconR.width + iconTextGap;
            g.fillRect(textPos, iconR.y, c.getWidth() - insets.right - textPos, componentRect.height);            
        }
    }
    

    Please, take into account, that here only the most common case is taken into account (Left-Right alignment, text right of the icon). For more complex case treatment see source code for SwingUtilities.layoutCompoundLabel