Wie zeichnet man einen Umriss um den Text in AWT?

Wie kann ich in AWT einen Umriss um einen beliebigen Text ziehen, ähnlich wie in diesem Bild?

Antworten auf die Frage(5)

- Geben Sie dieselben Wörter zweimal ein, aber eines davon ist schwarz und das andere ist weiß. Legen Sie Weiß über das Schwarze. Möglicherweise erhalten Sie etwas Ähnliches. -suchen Sie nach einer Schriftart, die über dem Beispiel aussieht, und verwenden Sie sie.

 Konrad Garus04. Apr. 2012, 19:19
Es ist sehr unwahrscheinlich, dass es im Allgemeinen funktioniert und ich brauche es, um gut auszusehen. Ich glaube nicht, dass MS oder Google dies in ihren Karten tun.

Versuche Folgendes:

<code>public void paintTextWithOutline(Graphics g) {
    String text = "some text";

    Color outlineColor = Color.white;
    Color fillColor = Color.black;
    BasicStroke outlineStroke = new BasicStroke(2.0f);

    if (g instanceof Graphics2D) {
        Graphics2D g2 = (Graphics2D) g;

        // remember original settings
        Color originalColor = g2.getColor();
        Stroke originalStroke = g2.getStroke();
        RenderingHints originalHints = g2.getRenderingHints();


        // create a glyph vector from your text
        GlyphVector glyphVector = getFont().createGlyphVector(g2.getFontRenderContext(), text);
        // get the shape object
        Shape textShape = glyphVector.getOutline();

        // activate anti aliasing for text rendering (if you want it to look nice)
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);

        g2.setColor(outlineColor);
        g2.setStroke(outlineStroke);
        g2.draw(textShape); // draw outline

        g2.setColor(fillColor);
        g2.fill(textShape); // fill the shape

        // reset to original settings after painting
        g2.setColor(originalColor);
        g2.setStroke(originalStroke);
        g2.setRenderingHints(originalHints);
    }
}
</code>
 sergpank27. Jan. 2019, 23:25
Dies ist die beste Antwort hier. Ich würde hinzufügen, dass es notwendig ist, den folgenden BasicStroke zu initialisieren: graphics.setStroke (neuer BasicStroke (Konturbreite, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); Andernfalls (ohne runde Kappe und Verbindung) kann es bei scharfen Winkeln zu unnötigen Artefakten kommen.

aber einfacher zu verstehen und verhält sich wie ein JLabel.

<code>public class OutlineLabel extends JLabel {

    private Color outlineColor = Color.WHITE;
    private boolean isPaintingOutline = false;
    private boolean forceTransparent = false;

    public OutlineLabel() {
        super();
    }

    public OutlineLabel(String text) {
        super(text);
    }

    public OutlineLabel(String text, int horizontalAlignment) {
        super(text, horizontalAlignment);
    }

    public Color getOutlineColor() {
        return outlineColor;
    }

    public void setOutlineColor(Color outlineColor) {
        this.outlineColor = outlineColor;
        this.invalidate();
    }

    @Override
    public Color getForeground() {
        if ( isPaintingOutline ) {
            return, outlineColor;
        } else {
            return super.getForeground();
        }
    }

    @Override
    public boolean isOpaque() {
        if ( forceTransparent ) {
            return false;
        } else {
            return super.isOpaque();
        }
    }

    @Override
    public void paint(Graphics g) {

        String text = getText();
        if ( text == null || text.length() == 0 ) {
            super.paint(g);
            return;
        }

        // 1 2 3
        // 8 9 4
        // 7 6 5

        if ( isOpaque() )
            super.paint(g);

        forceTransparent = true;
        isPaintingOutline = true;
        g.translate(-1, -1); super.paint(g); // 1 
        g.translate( 1,  0); super.paint(g); // 2 
        g.translate( 1,  0); super.paint(g); // 3 
        g.translate( 0,  1); super.paint(g); // 4
        g.translate( 0,  1); super.paint(g); // 5
        g.translate(-1,  0); super.paint(g); // 6
        g.translate(-1,  0); super.paint(g); // 7
        g.translate( 0, -1); super.paint(g); // 8
        g.translate( 1,  0); // 9
        isPaintingOutline = false;

        super.paint(g);
        forceTransparent = false;

    }

    public static void main(String[] args) {
        JFrame w = new JFrame();
        w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        OutlineLabel label = new OutlineLabel("Test", OutlineLabel.CENTER);
        label.setOpaque(true);
        w.setContentPane(new JPanel(new BorderLayout()));
        w.add(label, BorderLayout.CENTER);
        w.pack();
        w.setVisible(true);
    }
}
</code>
Lösung für das Problem

Schriftart und AffineTransform

Font, TextLayout und AffineTransform

Ausgabe von dieser Farbe wäre dieBufferedImageVerwenden Sie für AWT-Komponenten die Methodepaint(), für Swing ist JComponents dapaintComponet()

Aus Code, der in einem Kommentar verlinkt ist:

 Andrew Thompson05. Apr. 2012, 07:42
Oh ja, gute Punkte. Danke für die Erinnerung. :)
 Andrew Thompson05. Apr. 2012, 07:21
Siehe auchdiese Antwort wo (jenseits der Spezifikation) wende ich einen Rahmen auf die Form des Texts an.
 mKorbel05. Apr. 2012, 07:33
@ Andrew Thompson aaacch, danke,
 Andrew Thompson05. Apr. 2012, 07:23
Bitte vergib mir meine Bearbeitung. Wenn Sie der Meinung sind, dass dies für Ihre Antwort nicht geeignet ist, führen Sie einen Rollback durch. Aber ein Bild sagt mehr als tausend Worte ... oder in diesem Fall "Katze". ;)
 Andrew Thompson05. Apr. 2012, 07:30
"Für AWT-Komponenten verwenden .."  ..eine Zeitmaschine. Warum sie überhaupt erwähnen?
 mKorbel05. Apr. 2012, 07:37
@ Andrew Thompson, ein Teil der Leute benutzt SWT-AWT Bridge, ein Teil davon für OpenGL, sicher und niemand weiß, warum AWT für den wichtigsten Teil benutzt wird :-)

wie Sie den Text jetzt zeichnen, aber eine Möglichkeit, dies zu tun, besteht darin, ein gepuffertes Bild als Überlagerung für das zu zeichnende Objekt zu verwenden.

Erstellen Sie BufferedImage mit den Abmessungen des Strings und der Schriftart, mit denen Sie zeichnen möchten (siehe hierzu die FontMetrics-Klasse).Füllen Sie das gepufferte Bild mit Transparenz.Zeichnen Sie Ihren String mit der gewünschten Farbe auf das BufferedImage.Durchlaufen Sie jedes Pixel in BufferedImage und sehen Sie, wie weit es von einem Pixel Ihrer Textfarbe entfernt ist. Wenn es sich innerhalb eines bestimmten Abstands befindet, zeichnen Sie dieses Pixel schwarz und möglicherweise transparenter, wenn es weiter von der Farbe Ihres Texts entfernt ist. Wenn das Pixel bereits dieselbe Farbe wie Ihre Textfarbe hat, ignorieren Sie es natürlich.Zeichnen Sie BufferedImage auf das, worauf Sie malen.

BEARBEITEN

Möglicherweise gibt es Bibliotheken, die dies bereits tun, aber wenn ich es von Grund auf neu codieren müsste, würde ich versuchen, dies zu tun.

 Konrad Garus05. Apr. 2012, 11:04
Schöne Idee, auf jeden Fall einen Versuch wert. Vielen Dank.

Ihre Antwort auf die Frage