1

I wrote a program that collects at least 500 Wikipedia pages and links from these pages to other Wikipedia pages. It collects word frequencies from each webpage in order to determine the cost between two vertices(webpages) in a graph.

I am now trying to create a second program. I'm creating a GUI in NeatBeans using Swing where the user can select two webpages and then graphically see the shortest path between them. I am not sure how to visually display the graph. I have been looking into using JFreeChart or JUNG but neither seem to be capable of creating the kind of graph that I want.

Here is an example of what I am trying to create:

enter image description here

James
  • 69
  • 1
  • 1
  • 7
  • 1
    So your question is only about creating the graphics, and not about finding the shortest path in a graph? – user1803551 May 04 '15 at 23:47
  • yes, I can find the shortest path in the graph, I would like to graphically display the shortest path to the user and I do not know the best way of how to do that. – James May 05 '15 at 02:20
  • Very good. As I see it, you can use custom painting to draw everything, or use a combined approach of Swing components with custom painting on them. One thing is for sure, no need for any external packages, Did you ever do painting in Swing (using Graphics or Graphics2D objects)? – user1803551 May 05 '15 at 02:25

1 Answers1

2

I made something using only custom painting. If you do not know how to use cutom painting, the tutorial is a good place to start, see Performing Custom Painting and 2D Graphics.

enter image description here

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);
    }
}

Notes:

  • It is by no means an efficient (performance-wise) painting method. The loops runs twice, I turned on anti-aliasing etc.
  • The pixel calculations could be off (positions, sizes...).
  • The styles (colors, sizes...) are at your discretion.
  • The link grid is a simple but stupid implementation.
user1803551
  • 11,914
  • 5
  • 39
  • 63