Drawing a bordered path with sharp corners in Java

南笙酒味 提交于 2019-12-10 21:18:56

问题


I am working on an application that displays GPS tracks on a map. I want to draw the track as a colored path of arbitrary thickness. I found the GeneralPath class which seems to do just what I want. However, I want the colored path to also have a black border. I couldn't find anything about how to add a border to a path, so I came up with a quick hacky solution of drawing a thick black path first, and then drawing a thin colored path on top.

SSCCE:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;

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

public class PathBorder {
    private JFrame frame;

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

    public PathBorder() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel() {
            protected void paintComponent(Graphics g) {
                GeneralPath path;
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setStroke(new BasicStroke(5.5f));
                g2d.setColor(Color.BLACK);
                path = new GeneralPath();
                path.moveTo(0, 0);
                path.lineTo(100, 100);
                path.lineTo(200, 100);
                path.lineTo(100, 80);
                g2d.draw(path);
                g2d.setStroke(new BasicStroke(3));
                g2d.setColor(Color.YELLOW);
                g2d.draw(path);
            }
        };
        frame.setBackground(Color.CYAN);
        frame.add(panel);
    }
}

Here is a pic (taken from the SSCCE) to highlight my problem. See the red circle below, notice how the outside border has a gap in it. I want that gap to be filled in so the border is continuous.

Here are some actual screenshots from my app of a real track:

If you look closely at the sharp hairpin turn in the lower right of the track, you'll see that the border gets lost briefly... the detailed pic below makes it more clear.

I am not sure exactly how to fix this, but I'm open to suggestions, either keeping with the GeneralPath strategy, or using a different idea entirely.


回答1:


Experiment with the cap and join parameters for a better effect. E.G.

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;

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

public class PathBorder {

    private JFrame frame;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    PathBorder window = new PathBorder();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public PathBorder() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel() {

            GeneralPath path;

            protected void paintComponent(Graphics g) {
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                BasicStroke s = new BasicStroke(
                        5.5f, 
                        BasicStroke.CAP_ROUND, 
                        BasicStroke.JOIN_ROUND);
                g2d.setStroke(s);
                g2d.setColor(Color.BLACK);
                if (path==null) {
                    path = new GeneralPath();
                    path.moveTo(0, 0);
                    path.lineTo(100, 100);
                    path.lineTo(200, 100);
                    path.lineTo(100, 80);
                }
                g2d.draw(path);
                g2d.setStroke(new BasicStroke(3));
                g2d.setColor(Color.YELLOW);
                g2d.draw(path);
            }
        };
        frame.setBackground(Color.CYAN);
        frame.add(panel);
    }
}


来源:https://stackoverflow.com/questions/15039074/drawing-a-bordered-path-with-sharp-corners-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!