【问题标题】:Graphically display the shortest path between two vertices in a graph以图形方式显示图形中两个顶点之间的最短路径
【发布时间】:2015-05-04 21:46:26
【问题描述】:

我编写了一个程序,它收集了至少 500 个 Wikipedia 页面以及从这些页面到其他 Wikipedia 页面的链接。它从每个网页中收集词频,以确定图中两个顶点(网页)之间的成本。

我现在正在尝试创建第二个程序。我正在使用 Swing 在 NeatBeans 中创建一个 GUI,用户可以在其中选择两个网页,然后以图形方式查看它们之间的最短路径。我不确定如何直观地显示图表。我一直在研究使用 JFreeChartJUNG 但似乎都无法创建我想要的那种图表。

这是我正在尝试创建的示例:

【问题讨论】:

  • 所以您的问题只是关于创建图形,而不是关于在图中找到最短路径?
  • 是的,我可以在图中找到最短路径,我想以图形方式显示用户的最短路径,但我不知道如何做到这一点的最佳方式。
  • 非常好。正如我所看到的,您可以使用自定义绘画来绘制所有内容,或者使用 Swing 组件与自定义绘画的组合方法。有一件事是肯定的,不需要任何外部包,你有没有在 Swing 中画过(使用 Graphics 或 Graphics2D 对象)?

标签: java swing user-interface graph spanning-tree


【解决方案1】:

我只使用自定义绘画制作了一些东西。如果你不知道如何使用cutom画,教程是一个很好的起点,见Performing Custom Painting2D Graphics

public class Example extends JPanel {

    final static int GRID_SIZE = 4;
    final static int CELL_SIZE = 150;
    final static int CIRCLE_RAD = 20;
    final static int HALF_CIRCLE_WIDTH = 4;

    final static Color BACKGROUND = Color.WHITE;
    final static Color CIRCLE_FILL = new Color(185, 42, 42);
    final static Color CIRCLE_EDGE = Color.BLACK;
    final static Color LINK_FILL = Color.BLUE;
    final static Color NOLINK_FILL = new Color(150, 75, 0);

    final static BasicStroke LINK_STROKE = new BasicStroke(10);
    final static BasicStroke NOLINK_STROKE = new BasicStroke(2);
    final static BasicStroke CIRCLE_STROKE = new BasicStroke(HALF_CIRCLE_WIDTH);


    boolean[][][] links = new boolean[GRID_SIZE][GRID_SIZE][2];

    Example() {

        setBackground(BACKGROUND);

        Random rand = new Random();
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                links[i][j][0] = rand.nextBoolean(); // isLinkingtoRight
                links[i][j][1] = rand.nextBoolean(); // isLinkingtoDown
            }
        }
    }

    @Override
    public Dimension getPreferredSize() {

        int dim = CIRCLE_RAD * 2 + CELL_SIZE * (GRID_SIZE - 1) + HALF_CIRCLE_WIDTH * 2;
        return new Dimension(dim, dim);
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {

                if (j != GRID_SIZE - 1) {
                    if (links[i][j][0]) {
                        g2d.setColor(LINK_FILL);
                        g2d.setStroke(LINK_STROKE);
                    }
                    else {
                        g2d.setColor(NOLINK_FILL);
                        g2d.setStroke(NOLINK_STROKE);
                    }
                    g2d.drawLine(i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE  + CIRCLE_RAD + HALF_CIRCLE_WIDTH,
                                 i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, (j + 1) * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH);
                }
                if (i != GRID_SIZE - 1) {
                    if (links[i][j][1]) {
                        g2d.setColor(LINK_FILL);
                        g2d.setStroke(LINK_STROKE);
                    }
                    else {
                        g2d.setColor(NOLINK_FILL);
                        g2d.setStroke(NOLINK_STROKE);
                    }
                    g2d.drawLine(i * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH,
                                 (i + 1) * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH, j * CELL_SIZE + CIRCLE_RAD + HALF_CIRCLE_WIDTH);
                }
            }
        }

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(CIRCLE_STROKE);
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                g2d.setColor(CIRCLE_FILL);
                g2d.fillOval(i * CELL_SIZE + HALF_CIRCLE_WIDTH, j * CELL_SIZE + HALF_CIRCLE_WIDTH, CIRCLE_RAD * 2, CIRCLE_RAD * 2);
                g2d.setColor(CIRCLE_EDGE);
                g2d.drawOval(i * CELL_SIZE + HALF_CIRCLE_WIDTH, j * CELL_SIZE + HALF_CIRCLE_WIDTH, CIRCLE_RAD * 2, CIRCLE_RAD * 2);
            }
        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.add(new Example());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

注意事项:

  • 这绝不是一种高效(性能方面)的绘画方法。循环运行两次,我打开了抗锯齿等。
  • 像素计算可能已关闭(位置、大小...)。
  • 样式(颜色、尺寸...)由您自行决定。
  • 链接网格是一个简单但愚蠢的实现。

【讨论】:

  • 另见Initial Threads
  • @trashgod 查看我的个人资料以获取“不包括电池”免责声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 1970-01-01
相关资源
最近更新 更多