Search code examples
javaswinglinegraphic

Lines don't overlap when they should Java Swing


I'm drawing lines in a JFrame on a self made gridPanel.

Problem is, I draw the lines between 2 points. When I have a line that is between point 1 and point 2 and a line between point 2 and point 3, the lines should connect. This however isn,t the case, there is a small gap in between, no idea why. But it isn't drawing till the end of the specified point. (start point is correct.)

Here is the code of the JFrame:

public void initialize(){
     this.setLayout(new BorderLayout());

    this.setPreferredSize(new Dimension(500, 400));
    gridPane = new GridPane();
    gridPane.setBackground(Color.WHITE);
    gridPane.setSize(this.getPreferredSize());
    gridPane.setLocation(0, 0);
    this.add(gridPane,BorderLayout.CENTER);

    //createSampleLabyrinth();
    drawWall(0,5,40,5);  //These are the 2 lines that don't connect.
    drawWall(40,5,80,5);
    this.pack();
}

drawWall calls a method that calls a method in GridPane. The relevant code in gridPane:

/**
 * Draws a wall on this pane. With the starting point being x1, y1 and its end x2,y2.
 * @param x1
 * @param y1
 * @param x2
 * @param y2
 */
public void drawWall(int x1, int y1, int x2, int y2) {
    Wall wall = new Wall(x1,y1,x2,y2, true);
    wall.drawGraphic();
    wall.setLocation(x1, y1);
    wall.setSize(10000,10000);
    this.add(wall, JLayeredPane.DEFAULT_LAYER);
    this.repaint();
}

This method creates a wall and puts it in the Jframe. The relevant code of the wall:

public class Wall extends JPanel {
private int x1;
private int x2;
private int y1;
private int y2;
private boolean black;

/**
 * x1,y1 is the start point of the wall (line) end is x2,y2
 * 
 * @param x1
 * @param y1
 * @param x2
 * @param y2
 */
public Wall(int x1, int y1, int x2, int y2, boolean black) {
    this.x1 = x1;
    this.x2 = x2;
    this.y1 = y1;
    this.y2 = y2;
    this.black = black;
    setOpaque(false);
}

private static final long serialVersionUID = 1L;

public void drawGraphic() {
    repaint();
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    if(black){
        g2.setColor(Color.BLACK);
        g2.setStroke(new BasicStroke(8));
    } else {
        g2.setColor(Color.YELLOW);
        g2.setStroke(new BasicStroke(3));
    }
    g2.drawLine(x1, y1, x2, y2);
}

}

So, where am I going wrong? The true/false is to determine if the wall should be black or yellow, nothing to be concerned about.


Solution

  • You've set the main layout as BorderLayout using this.setLayout(new BorderLayout());

    You then add the GridPane to the center position this.add(gridPane,BorderLayout.CENTER);

    You then try and add the walls to the main layout using this.add(wall, JLayeredPane.DEFAULT_LAYER); ... But the main layout is a BorderLayout

    This is going to cause you some issues

    UPDATED

    The other problem you have is in the Wall#paintComponent method.

    You are drawing the lines offset from the x1 and y1 positions, but the component has already being positioned at this point.

    The top, left corner of any component is always 0x0

    The line g2.drawLine(x1, y1, x2, y2); should read more like...

    int x = x2 - x1;
    int y = y2 - y1;
    g2.drawLine(0, 0, x, y);
    

    UPDATED

    You should also avoid setting the size of your components to some arbitary value (such 1000x1000) and rely more on the ability for your components to give you feedback...

    public Dimension getPreferredSize() {
        int width = Math.max(x1, x2) - Math.min(x1, x2);
        int height = Math.max(y1, y2) - Math.min(y1, y2);
    
        if (black) {
            width += 8;
            height += 8;
        } else {
            width += 3;
            height += 3;
        }
    
        return new Dimension(width, height);
    }
    

    Then when adding the Wall, you can use wall.setSize(wall.getPreferredSize()) instead...