Search code examples
javaswingborder

Java Swing - BasicStroke smaller to the left


I'm writing a simple 2D chess game with Java Swing but I have encountered a problem with BasicStroke: the left side is smaller than the right side.

chess board image

In the case of the image, the left side is smaller by 5 pixels (calculated with GIMP).

This is the class that realizes the interface

public class ChessInterface extends JComponent
{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    private static final int CHESS_BOARD_SIZE = 500;
    
    // class for managing the chess board
    private Board board;

    private int pieceSize;
    
    // space to center the board
    private int space;
    
    private Image table;
    
    private Image cellDark, cellLight;

    private Map<String, Image> pieceImages;

    public ChessInterface(Board board)
    {
        this.board = board;
        pieceSize = CHESS_BOARD_SIZE / 8;
        // 800 is the parent size
        space = (800 - CHESS_BOARD_SIZE) / 2;
        try
        {
            table = ImageIO.read(ChessInterface.class.getResourceAsStream("/images/table.jpg"));
            cellLight = ImageIO.read(ChessInterface.class.getResourceAsStream("/images/wood_light.png"));
            cellDark = ImageIO.read(ChessInterface.class.getResourceAsStream("/images/wood_dark.png"));
            pieceImages = new HashMap<>();
            // pieces image are converted from .svg to .png with Batik
            board.getPieces().forEach(e -> {
                Image pieceImage = pieceImages.get(e.getImage());
                if (pieceImage == null)
                {
                    ImgTranscoder transcoder = new ImgTranscoder();
                    transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) pieceSize);
                    transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) pieceSize);
                    try (InputStream input = getClass().getResourceAsStream(e.getImage()))
                    {
                        TranscoderInput trInput = new TranscoderInput(input);
                        transcoder.transcode(trInput, null);
                        pieceImage = transcoder.getImage();
                        pieceImages.put(e.getImage(), pieceImage);
                    }
                    catch (TranscoderException | IOException e1)
                    {
                        e1.printStackTrace();
                    }
                }
            });
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        
        RenderingHints qualityHints = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        qualityHints.put(
            RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHints(qualityHints);
        
        // draw the wooden background
        g2.drawImage(table, 0, 0, null);
        
        // draw the rounded border
        Rectangle boardRectangle = new Rectangle(space, space, CHESS_BOARD_SIZE, CHESS_BOARD_SIZE);
        Stroke old = g2.getStroke();
        g2.setColor(Color.BLACK);
        g2.setStroke(new BasicStroke(100,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
        g2.draw(boardRectangle);
        g2.setStroke(old);
        
        // draw cells and pieces
        for(int i=8; i>=1; i--)
        {
            for(char j='a'; j <= 'h'; j++)
            {
                Image cell = (i + j) % 2 == 0 ? cellDark : cellLight;
                Piece piece = board.getPiece(new Position(i,j));
                int x = space + pieceSize * (j - 'a');
                int y = space + pieceSize * (8 - i);
                g2.drawImage(cell, x, y, pieceSize, pieceSize, null);
                if (piece != null)
                    g2.drawImage(pieceImages.get(piece.getImage()), x, y, null);
            }
        }
        g2.dispose();
    }
}

I really don't know how to solve.

Thanks in advance.


Solution

  • I solved by following this answer

    This is my code

    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
            
        RenderingHints qualityHints = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        qualityHints.put(
            RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);
        g2.setRenderingHints(qualityHints);
            
        g2.drawImage(table, 0, 0, null);
        
        int borderWidth = 20;
        
        g2.setColor(Color.BLACK);
        g2.fillRoundRect(space - borderWidth, space - borderWidth, CHESS_BOARD_SIZE +
            borderWidth * 2, CHESS_BOARD_SIZE + borderWidth * 2, 20, 20);
            
        for(int i=8; i>=1; i--)
        {
            for(char j='a'; j <= 'h'; j++)
            {
                Image cell = (i + j) % 2 == 0 ? cellDark : cellLight;
                Piece piece = board.getPiece(new Position(i,j));
                int x = space + pieceSize * (j - 'a');
                int y = space + pieceSize * (8 - i);
                g2.drawImage(cell, x, y, pieceSize, pieceSize, null);
                if (piece != null)
                    g2.drawImage(pieceImages.get(piece.getImage()), x, y, null);
            }
        }
    }
    

    Result

    chess board image