在圆形秋千边界外面切割背景

时间:2014-12-11 11:58:32

标签: java swing border rounded-corners

我制作了自己的RoundedBorder,而不是使用圆角的LineBorder,因为我想设置圆弧大小。

public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D) g;

    Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
                                                  y + thickness / 2,
                                                  width - thickness,
                                                  height - thickness,
                                                  arcSize,
                                                  arcSize);
    Area area = new Area(roundRect);

    g2.setColor(color);
    g2.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
    g2.setStroke(new BasicStroke(thickness));

    g2.draw(area);
}

enter image description here



我使用border-with-rounded-corners-transparency中的一些代码来使用圆形边框之外的父背景颜色。虽然它与TitledBorder不能正常使用RoundedBorder,因为它只与RoundedBorder一起使用。将以下代码添加到我的paintBorder。

    Component parent = c.getParent();
    if (parent != null) {
        Color bg = parent.getBackground();
        Rectangle rect = new Rectangle(x, y, width, height);
        Area borderRegion = new Area(rect);
        borderRegion.subtract(area);
        g2.setClip(borderRegion);
        g2.setColor(bg);
        g2.fillRect(x, y, width, height);
        g2.setClip(null);
    }


知道如何解决这个问题才能正常工作? enter image description here



编辑:paintBorder的一个新实现让我更接近:

    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D) g;

    Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
                                                  y + thickness / 2,
                                                  width - thickness,
                                                  height - thickness,
                                                  arcSize,
                                                  arcSize);
    Area area = new Area(roundRect);

    final Rectangle componentRect = c.getBounds();
    final int componentWidth = (int) componentRect.getWidth();
    final int componentHeight = (int) componentRect.getWidth();

    // Paint the BG color of the parent in the entire rectangle of the component. 
    // Then repaint the area inside the border.
    Component parent = c.getParent();
    if (parent != null) {
        g2.setColor(parent.getBackground());
        g2.fillRect(0, 0, componentWidth, componentHeight);

        g2.setColor(c.getBackground());
        g2.fillRoundRect(x + thickness / 2,
                         y + thickness / 2,
                         width - thickness,
                         height - thickness,
                         arcSize,
                         arcSize);
    }

    g2.setColor(color);
    g2.setRenderingHints(hints);
    g2.setStroke(stroke);
    g2.draw(area);
}

enter image description here

测试代码解决方案1:

package com.test.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.AbstractBorder;
import javax.swing.border.TitledBorder;

public class TestBorderApp {

private JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                TestBorderApp window = new TestBorderApp();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public TestBorderApp() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel mainpanel = new JPanel();

    JPanel panel1 = new JPanel();
    panel1.setBackground(Color.RED);
    RoundedBorder roundBorder1 = new RoundedBorder(Color.BLACK, 5, 60);
    TitledBorder titleBorder1 = BorderFactory.createTitledBorder(roundBorder1, 
                        "Title", 
                        TitledBorder.CENTER, 
                        TitledBorder.ABOVE_TOP,
                        Font.decode(Font.SANS_SERIF), 
                        Color.BLACK);
    panel1.setBorder(titleBorder1);
    JLabel label1 = new JLabel("Text Text Text");
    panel1.add(label1);
    mainpanel.add(panel1);

    JPanel panel2 = new JPanel();
    panel2.setBackground(Color.RED);
    RoundedBorder roundBorder2 = new RoundedBorder(Color.BLACK, 5, 60);
    TitledBorder titleBorder2 = BorderFactory.createTitledBorder(roundBorder2, 
                        "Title", 
                        TitledBorder.CENTER, 
                        TitledBorder.TOP,
                        Font.decode(Font.SANS_SERIF), 
                        Color.BLACK);
    panel2.setBorder(titleBorder2);
    JLabel label2 = new JLabel("Text Text Text");
    panel2.add(label2);
    mainpanel.add(panel2);

    JPanel panel3 = new JPanel();
    panel3.setBackground(Color.RED);
    RoundedBorder roundBorder3 = new RoundedBorder(Color.BLACK, 5, 60);
    TitledBorder titleBorder3 = BorderFactory.createTitledBorder(
                        roundBorder3, 
                        "Title", 
                        TitledBorder.CENTER, 
                        TitledBorder.BELOW_TOP, 
                        Font.decode(Font.SANS_SERIF), 
                        Color.BLACK);
    panel3.setBorder(titleBorder3);
    JLabel label3 = new JLabel("Text Text Text");
    panel3.add(label3);
    mainpanel.add(panel3);

    frame.setContentPane(mainpanel);
}

public class RoundedBorder extends AbstractBorder {

    private static final long serialVersionUID = -6244878594068693694L;

    private Color color;

    private int thickness = 4;

    private int arcSize = 8;

    private BasicStroke stroke;

    private RenderingHints hints;

    /**
     * Constructor for round border
     *
     * @param color
     *            The color
     * @param thickness
     *            The thickness
     * @param arcSize
     *            the arc size
     */
    public RoundedBorder(Color color, int thickness, int arcSize) {
        this.thickness = thickness;
        this.arcSize = arcSize;
        this.color = color;
        this.stroke = new BasicStroke(thickness);
        this.hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    }

    /**
     * Set the current color of the border
     *
     * @param color
     *            The color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    /**
     * Get the current color of the border
     *
     * @return
     */
    public Color getColor() {
        return color;
    }

    public void setArcSize(int arcSize) {
        this.arcSize = arcSize;
    }

    public int getArcSize() {
        return arcSize;
    }

    /* (non-Javadoc)
     * @see javax.swing.border.AbstractBorder#getBorderInsets(java.awt.Component, java.awt.Insets)
     */
    @Override
    public Insets getBorderInsets(Component c, Insets i) {
        i.set(thickness, thickness, thickness, thickness);
        return i;
    }

    /* (non-Javadoc)
     * @see javax.swing.border.AbstractBorder#paintBorder(java.awt.Component, java.awt.Graphics, int, int, int, int)
     */
    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2 = (Graphics2D) g;

        Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
                                                      y + thickness / 2,
                                                      width - thickness,
                                                      height - thickness,
                                                      arcSize,
                                                      arcSize);
        Area area = new Area(roundRect);

        // Paint the BG color of the parent, everywhere outside the clip of the text bubble.
        Component parent = c.getParent();
        if (parent != null) {
            Color bg = parent.getBackground();
            Rectangle rect = new Rectangle(x, y, width, height);
            Area borderRegion = new Area(rect);
            borderRegion.subtract(area);
            g2.setClip(borderRegion);
            g2.setColor(bg);
            g2.fillRect(0, 0, width, height);
            g2.setClip(null);
        }

        g2.setColor(color);
        g2.setRenderingHints(hints);
        g2.setStroke(stroke);

        g2.draw(area);
    }

}
}

测试代码解决方案2:

package com.test.gui;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.AbstractBorder;
import javax.swing.border.TitledBorder;

public class TestBorderApp {

private JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                TestBorderApp window = new TestBorderApp();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public TestBorderApp() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel mainpanel = new JPanel();

    JPanel panel1 = new JPanel();
    panel1.setBackground(Color.RED);
    RoundedBorder roundBorder1 = new RoundedBorder(Color.BLACK, 5, 60);
    TitledBorder titleBorder1 = BorderFactory.createTitledBorder(roundBorder1, 
                        "Title", 
                        TitledBorder.CENTER, 
                        TitledBorder.ABOVE_TOP,
                        Font.decode(Font.SANS_SERIF), 
                        Color.BLACK);
    panel1.setBorder(titleBorder1);
    JLabel label1 = new JLabel("Text Text Text");
    panel1.add(label1);
    mainpanel.add(panel1);

    JPanel panel2 = new JPanel();
    panel2.setBackground(Color.RED);
    RoundedBorder roundBorder2 = new RoundedBorder(Color.BLACK, 5, 60);
    TitledBorder titleBorder2 = BorderFactory.createTitledBorder(roundBorder2, 
                        "Title", 
                        TitledBorder.CENTER, 
                        TitledBorder.TOP,
                        Font.decode(Font.SANS_SERIF), 
                        Color.BLACK);
    panel2.setBorder(titleBorder2);
    JLabel label2 = new JLabel("Text Text Text");
    panel2.add(label2);
    mainpanel.add(panel2);

    JPanel panel3 = new JPanel();
    panel3.setBackground(Color.RED);
    RoundedBorder roundBorder3 = new RoundedBorder(Color.BLACK, 5, 60);
    TitledBorder titleBorder3 = BorderFactory.createTitledBorder(
                        roundBorder3, 
                        "Title", 
                        TitledBorder.CENTER, 
                        TitledBorder.BELOW_TOP, 
                        Font.decode(Font.SANS_SERIF), 
                        Color.BLACK);
    panel3.setBorder(titleBorder3);
    JLabel label3 = new JLabel("Text Text Text");
    panel3.add(label3);
    mainpanel.add(panel3);

    frame.setContentPane(mainpanel);
}

public class RoundedBorder extends AbstractBorder {

    private static final long serialVersionUID = -6244878594068693694L;

    private Color color;

    private int thickness = 4;

    private int arcSize = 8;

    private BasicStroke stroke;

    private RenderingHints hints;

    /**
     * Constructor for round border
     *
     * @param color
     *            The color
     * @param thickness
     *            The thickness
     * @param arcSize
     *            the arc size
     */
    public RoundedBorder(Color color, int thickness, int arcSize) {
        this.thickness = thickness;
        this.arcSize = arcSize;
        this.color = color;
        this.stroke = new BasicStroke(thickness);
        this.hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    }

    /**
     * Set the current color of the border
     *
     * @param color
     *            The color
     */
    public void setColor(Color color) {
        this.color = color;
    }

    /**
     * Get the current color of the border
     *
     * @return
     */
    public Color getColor() {
        return color;
    }

    public void setArcSize(int arcSize) {
        this.arcSize = arcSize;
    }

    public int getArcSize() {
        return arcSize;
    }

    /* (non-Javadoc)
     * @see javax.swing.border.AbstractBorder#getBorderInsets(java.awt.Component, java.awt.Insets)
     */
    @Override
    public Insets getBorderInsets(Component c, Insets i) {
        i.set(thickness, thickness, thickness, thickness);
        return i;
    }

    /* (non-Javadoc)
     * @see javax.swing.border.AbstractBorder#paintBorder(java.awt.Component, java.awt.Graphics, int, int, int, int)
     */
    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2 = (Graphics2D) g;

        Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
                                                      y + thickness / 2,
                                                      width - thickness,
                                                      height - thickness,
                                                      arcSize,
                                                      arcSize);
        Area area = new Area(roundRect);

        final Rectangle componentRect = c.getBounds();
        final int componentWidth = (int) componentRect.getWidth();
        final int componentHeight = (int) componentRect.getWidth();

        // Paint the BG color of the parent in the entire rectangle of the component.
        // Then repaint the area inside the border.
        Component parent = c.getParent();
        if (parent != null) {
            g2.setColor(parent.getBackground());
            g2.fillRect(0, 0, componentWidth, componentHeight);

            g2.setColor(c.getBackground());
            g2.fillRoundRect(x + thickness / 2,
                             y + thickness / 2,
                             width - thickness,
                             height - thickness,
                             arcSize,
                             arcSize);
        }

        g2.setColor(color);
        g2.setRenderingHints(hints);
        g2.setStroke(stroke);
        g2.draw(area);
    }

}}

0 个答案:

没有答案