java - 带有字符 g.draw java 的轮廓形状

标签 java awt java-2d japplet

所以基本上我需要制作星号的形状,如下图所示:

http://i.imgur.com/BZxrwij.png

这就是我当前的解决方案。

import java.applet.Applet;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Stroke;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class ThreePointTen extends Applet{
    public void init(String[] a) {

  }

public void paint(Graphics g){
     char a = '*'; 
    //square
       g.drawString("**********", 25, 25);
       g.drawString("*              *", 25, 35);
       g.drawString("*              *", 25, 45);
       g.drawString("*              *", 25, 55);
       g.drawString("*              *", 25, 65);
       g.drawString("*              *", 25, 75);
       g.drawString("*              *", 25, 85);
       g.drawString("*              *", 25, 95);
       g.drawString("**********", 25, 105);

   //oval
       g.drawString("***", 175, 25);
       g.drawString("*         * ", 165, 35);
       g.drawString("*             * ", 158, 45);
       g.drawString("*             * ", 158, 55);
       g.drawString("*             * ", 158, 65);
       g.drawString("*             * ", 158, 75);
       g.drawString("*             * ", 158, 85);
       g.drawString("*         * ", 165, 95);
       g.drawString("***", 175, 105);

    }

}

我基本上只是猜测如何制作每个形状以及它们的去向。这种方法极其缓慢且低效。我想知道是否可以使用 g.draw 制作一个形状,然后如何用一个角色勾勒出它的轮廓。

最佳答案

您可以创建一个特殊的Stroke,其内部由这些星号/星星组成。然后,您可以使用 Stroke.createStrokedShape(shape) 创建一个新形状,该形状代表使用此笔画绘制的另一个形状。

http://www.jhlabs.com/java/java2d/strokes/ 有一个这样的笔划的(Apache 许可的)实现。 (也包含在下面的代码中,带有链接和版权信息)

三个结果可能如下所示:

Stars!

使用以下独立示例创建:

import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class StarShapes
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new StarShapesPanel());
        f.setSize(600,400);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

}

class StarShapesPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        Font starFont = new Font("Monospaced", Font.BOLD, 20);
        Shape starShape = createShape(starFont, "*");
        Stroke stroke = new ShapeStroke(new Shape[] { starShape }, 12.0f);

        Font textFont = new Font("Serif", Font.PLAIN, 250);
        Shape textShape = createShape(textFont,  "Stars!");
        g.translate(10,  250);
        Shape strokedTextShape = 
            stroke.createStrokedShape(textShape);
        g.fill(strokedTextShape);
    }

    private static Shape createShape(Font font, String s)
    {
        FontRenderContext fontRenderContext = 
            new FontRenderContext(null,true,true);
        GlyphVector glyphVector = 
            font.createGlyphVector(fontRenderContext, s);
        return glyphVector.getOutline();
    }

}



//============================================================================
// From http://www.jhlabs.com/java/java2d/strokes/

/*
Copyright 2006 Jerry Huxtable

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

class ShapeStroke implements Stroke {
    private Shape shapes[];
    private float advance;
    private boolean stretchToFit = false;
    private boolean repeat = true;
    private AffineTransform t = new AffineTransform();
    private static final float FLATNESS = 1;

    public ShapeStroke( Shape shapes, float advance ) {
        this( new Shape[] { shapes }, advance );
    }

    public ShapeStroke( Shape shapes[], float advance ) {
        this.advance = advance;
        this.shapes = new Shape[shapes.length];

        for ( int i = 0; i < this.shapes.length; i++ ) {
            Rectangle2D bounds = shapes[i].getBounds2D();
            t.setToTranslation( -bounds.getCenterX(), -bounds.getCenterY() );
            this.shapes[i] = t.createTransformedShape( shapes[i] );
        }
    }

    public Shape createStrokedShape( Shape shape ) {
        GeneralPath result = new GeneralPath();
        PathIterator it = new FlatteningPathIterator( shape.getPathIterator( null ), FLATNESS );
        float points[] = new float[6];
        float moveX = 0, moveY = 0;
        float lastX = 0, lastY = 0;
        float thisX = 0, thisY = 0;
        int type = 0;
        boolean first = false;
        float next = 0;
        int currentShape = 0;
        int length = shapes.length;

        float factor = 1;

        while ( currentShape < length && !it.isDone() ) {
            type = it.currentSegment( points );
            switch( type ){
            case PathIterator.SEG_MOVETO:
                moveX = lastX = points[0];
                moveY = lastY = points[1];
                result.moveTo( moveX, moveY );
                first = true;
                next = 0;
                break;

            case PathIterator.SEG_CLOSE:
                points[0] = moveX;
                points[1] = moveY;
                // Fall into....

            case PathIterator.SEG_LINETO:
                thisX = points[0];
                thisY = points[1];
                float dx = thisX-lastX;
                float dy = thisY-lastY;
                float distance = (float)Math.sqrt( dx*dx + dy*dy );
                if ( distance >= next ) {
                    float r = 1.0f/distance;
                    float angle = (float)Math.atan2( dy, dx );
                    while ( currentShape < length && distance >= next ) {
                        float x = lastX + next*dx*r;
                        float y = lastY + next*dy*r;
                        t.setToTranslation( x, y );
                        t.rotate( angle );
                        result.append( t.createTransformedShape( shapes[currentShape] ), false );
                        next += advance;
                        currentShape++;
                        if ( repeat )
                            currentShape %= length;
                    }
                }
                next -= distance;
                first = false;
                lastX = thisX;
                lastY = thisY;
                break;
            }
            it.next();
        }

        return result;
    }

}

关于java - 带有字符 g.draw java 的轮廓形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32973792/

相关文章:

java - Canvas 显示问题

java - 具有多个键的菜单快捷方式

java - 无法获得正确的字体字符宽度

Java2D Artifact ?

java - 使用 RPC/编码网络服务的最佳方式?

java - 不可变类中的对象作为成员变量

java - 提交表单时渲染 wicket 组件

java - 在 Android 中使用 Mapbox SDK 绘制圆

java - 使用鼠标和图形缩放

java - 在黑色 JFrame 上绘制线条