/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2010, Johann Sorel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.gui.swing.util;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.JComponent;
import javax.swing.border.Border;
/**
* Eye candys util class to remove a border from a component.
* Nice effect when placing several buttons next to each other without borders.
*
* @author Johann Sorel (Puzzle-GIS)
* @module
*/
public class BorderCutter {
private BorderCutter(){}
public static JComponent cut(final JComponent sub, final boolean top, final boolean bottom, final boolean left, final boolean right){
return new JCutter(sub,top,bottom,left,right);
}
/**
* I tryed several approches to remove a border from a component.
* - Cutting border : didn't work on all L&F. some L&F do not use the paintBorder method
* to render the border, for exemple the linux L&F. other like Metal or Nimbus were working.
* - Layout : only moves the component
* - Override : must overide every possible component class, to much work.
*
* The choosen approach is to make him think there is a component (and so preserver all events).
* but render it cutted by it's parent. We must override the Paint method and not PaintComponent otherwise
* some L&F bypass the current component to direction paint the childrens (but we don't want that).
* The sub component must not be opaque, otherwise if it overlaps completely the parent then the parent paint
* method will be ignored.
*/
private static class JCutter extends JComponent{
private final JComponent sub;
private final boolean top;
private final boolean bottom;
private final boolean left;
private final boolean right;
private JCutter(final JComponent sub, final boolean top, final boolean bottom, final boolean left, final boolean right){
this.top = top;
this.bottom = bottom;
this.left = left;
this.right = right;
this.sub = sub;
sub.setOpaque(false);
add(sub);
}
@Override
public Dimension getPreferredSize() {
final Dimension dim = sub.getPreferredSize();
final Border border = sub.getBorder();
if(border != null){
final Insets insets = border.getBorderInsets(sub);
if(bottom){
dim.height -= insets.bottom;
}
if(top){
dim.height -= insets.top;
}
if(left){
dim.width -= insets.left;
}
if(right){
dim.width -= insets.right;
}
}
return dim;
}
@Override
public void paint(final Graphics g) {
final Dimension dim = getSize();
final Border border = sub.getBorder();
if(border != null){
final Insets insets = border.getBorderInsets(sub);
if(bottom){
dim.height += insets.bottom;
}
if(top){
dim.height += insets.top;
g.translate(0, -insets.top);
}
if(left){
dim.width += insets.left;
g.translate(-insets.left, 0);
}
if(right){
dim.width += insets.right;
}
}
sub.setSize(dim);
sub.paint(g);
}
}
}