Как я могу кодировать грязную богатую градиентно окрашенную границу, используя Java Swing - PullRequest
4 голосов
/ 14 марта 2011

Пересмотрено: проблема в том, чтобы нарисовать четырехстороннюю границу, где каждая сторона начинается со сплошного базового цвета и постепенно исчезает внутри на протяжении промежутка границы.Задача состояла в том, чтобы пересечение границ выглядело гладко.Для этого можно нарисовать границы, а затем использовать треугольники, чтобы «смешать» углы.Для каждого угла можно использовать два треугольника, если в прямоугольниках, перекрывающих ширину, нет перекрытия или достаточно одного треугольника на угол (как показано ниже), если две параллельные граничные стороны расширяют всю длину границы (т.е. прямоугольники перекрываются).


    private static final int GRADIENT_LENGTH = 29;
    private static final int BAR_LENGTH = 25;
    public static void paintGradientBorder(Graphics g, Color borderColor) {</p>

<pre><code>    Graphics2D g2 = (Graphics2D) g.create();

    GradientPaint gradientColorWest = new GradientPaint(0, 0, borderColor,
            GRADIENT_LENGTH, 0, Color.WHITE);
    GradientPaint gradientColorEast = new GradientPaint(WINDOW_WIDTH - GRADIENT_LENGTH,
            0, Color.WHITE, WINDOW_WIDTH, 0, borderColor);
    GradientPaint gradientColorNorth= new GradientPaint(0, 0, borderColor, 0,
            GRADIENT_LENGTH, Color.WHITE);
    GradientPaint gradientColorSouth = new GradientPaint(0, WINDOW_HEIGHT - GRADIENT_LENGTH,
            Color.WHITE,0, WINDOW_HEIGHT, borderColor);

    //south bar
    g2.setPaint(gradientColorSouth);
    g2.fillRect(0, WINDOW_HEIGHT - BAR_LENGTH, WINDOW_WIDTH, BAR_LENGTH);
    //north bar
    g2.setPaint(gradientColorNorth);
    g2.fillRect(0, 0, WINDOW_WIDTH, BAR_LENGTH);
    //west bar
    g2.setPaint(gradientColorWest);
    g2.fillRect(0, BAR_LENGTH, BAR_LENGTH, WINDOW_HEIGHT - BAR_LENGTH * 2);
    //east bar
    g2.setPaint(gradientColorEast);
    g2.fillRect(WINDOW_WIDTH - BAR_LENGTH, BAR_LENGTH, WINDOW_WIDTH, WINDOW_HEIGHT - BAR_LENGTH * 2);

    //NORTH WEST CORNER
    //left triangle
    Polygon p = new Polygon();        
    p.addPoint(0, 0);
    p.addPoint(BAR_LENGTH, BAR_LENGTH);
    p.addPoint(0, BAR_LENGTH);
    g2.setPaint(gradientColorWest);
    g2.fillPolygon(p);        
    //NORTH EAST CORNER
    //right triangle
    p.reset();
    p.addPoint(WINDOW_WIDTH, 0);
    p.addPoint(WINDOW_WIDTH - BAR_LENGTH, BAR_LENGTH);
    p.addPoint(WINDOW_WIDTH, BAR_LENGTH);
    g2.setPaint(gradientColorEast);
    g2.fillPolygon(p);
    //SOUTH WEST CORNER
    //left triangle
    p.reset();
    p.addPoint(0, WINDOW_HEIGHT);
    p.addPoint(0,WINDOW_HEIGHT - BAR_LENGTH);
    p.addPoint(BAR_LENGTH, WINDOW_HEIGHT - BAR_LENGTH);
    g2.setPaint(gradientColorWest);
    g2.fillPolygon(p);
    //SOUTH EAST CORNER
    //right triangle
    p.reset();
    p.addPoint(WINDOW_WIDTH, WINDOW_HEIGHT);
    p.addPoint(WINDOW_WIDTH, WINDOW_HEIGHT - BAR_LENGTH);
    p.addPoint(WINDOW_WIDTH - BAR_LENGTH, WINDOW_HEIGHT - BAR_LENGTH);
    g2.setPaint(gradientColorEast);
    g2.fillPolygon(p);

    g2.dispose();
}

Ответы [ 2 ]

5 голосов
/ 14 марта 2011

Что если вы не пересекаете прямоугольники, а вместо этого используете многоугольник (GeneralPath)?

GeneralPath topBox = new GeneralPath();
topBox.moveTo(0, 0);
// upper right
topBox.lineTo(width, 0);
// lower right; move diagonally down and to the left as in a picture frame
topBox.lineTo(width - (insetX / 2), 0 + (insetY / 2));
// lower left
topBox.lineTo((insetX / 2), 0 + (insetY / 2));
topBox.closePath();
g2.fill(topBox);

enter image description here

Таким образом, прямоугольники не будут перекрываться, но вместо этого выбудет иметь отличные четкие края между различными сегментами.

3 голосов
/ 14 марта 2011

Вместо того, чтобы создавать и рисовать 4 прямоугольника, я бы создал один Shape, представляющий вашу граничную область, вычитая внутренний прямоугольник из внешнего с помощью Area:

Area area = new Area(new Rectangle2D.Double(...));
Area inner = new Area(new Rectangle2D.Double(...));
area.subtract(inner);

g2.setPaint(new GradientPaint(...));
g2.fill(area);
...