Home > database >  How to add a JPanel to JFrame without deleting currently drawn graphics?
How to add a JPanel to JFrame without deleting currently drawn graphics?

Time:08-09

I am in the process of making a basic chess game using java gui (swing, awt). I found though that 1, only the board drawn in JFrame initially shows up, and 2, while the image of a piece appears when I start dragging my cursor, the board disappears and just leaves the draggable image. How can I get the image to initially be visible and not remove the board when I drag it?

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Color;

public class BoardGUI extends JFrame {
    
    public BoardGUI()
    {
        this.setSize(1000,1000);
        this.setTitle("Chess");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        PieceImage king = new PieceImage("./king.png",500,800);
        this.add(king);
        this.setVisible(true);
    }
    
    public void paint(Graphics g)
    {
        int[] swap  = {1,2};
        String[] rowNum = {"8","7","6","5","4","3","2","1"};
        String[] ColumnLetter = {"A","B","C","D","E","F","G","H"};
        int rowCount = 0;
        int columnCount = 0;
        for(int i=100;i<900;i =100)
        {
            for(int j=100;j<900;j =100)
            {
                if(i==100)
                {
                    g.setColor(Color.black);
                    g.drawString(rowNum[rowCount  ],i-20,j 60);
                }
                if(j==100)
                {
                    g.setColor(Color.black);
                    g.drawString(ColumnLetter[columnCount  ],i 50,j 820);
                }
                if(swap[0] == 1)
                    g.setColor(Color.white);
                else
                    g.setColor(Color.black);
                swapColor(swap);
                g.fillRect(i,j,100,100);
                if(j==800)
                    swapColor(swap);
            }
        }
    }
    
    private void swapColor(int[] swap)
    {
        int temp = swap[0];
        swap[0] = swap[1];
        swap[1] = temp;
    }
}

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Graphics;
import java.awt.Point;

public class PieceImage extends JPanel {
    private ImageIcon image;
    private Point prevPos; 
    private Point pos; 
    
    public PieceImage(String imagePath, int xPos, int yPos)
    {
        if(imagePath==null)
            return;
        this.image = new ImageIcon(imagePath);
        this.pos = new Point(xPos,yPos);
        
        ClickListener clickListner = new ClickListener();
        DragListener dragListener = new DragListener();
        
        this.addMouseListener(clickListner);
        this.addMouseMotionListener(dragListener);
    }
    
    
    private class ClickListener extends MouseAdapter {
        
        public void mousePressed(MouseEvent e)
        {
            prevPos = e.getPoint();
        }
    }
    
    private class DragListener extends MouseInputAdapter {
        
        public void mouseDragged(MouseEvent e)
        {
            Point temp = e.getPoint();
            pos.translate((int)(temp.getX() - prevPos.getX())-50, (int)(temp.getY() - prevPos.getY())-50);
            
            prevPos = pos;
            repaint();
        }
    }
    
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        image.paintIcon(this, g, (int)pos.getX(), (int)pos.getY());
    }
}

CodePudding user response:

You should not override the paint() method of the JFrame.

The JFrame is your top-level-container, that should contain components, which can be painted however you want. So instead of overwriting the paint() method, you should go for a better approach. I will give you some advice to create a chess game in Swing:

  • I personally never use the JFrame itself, I usually place a JPanel inside that fills the whole JFrame.

  • You can use this JPanel and set its Layout to JPanel.setLayout(new GridLayout(8, 8)). This will give you a complete and responsive chess field, which can be filled with whatever component you want.

  • Make use of the BorderLayout to place the position letters and numbers at the top (NORTH), left (WEST) or where ever you want.

  • To implement a Drag&Drop based game, an easy way to do so is placing 64 JButtons inside the GridLayout and Adding MouseListener MouseMotionListener. The methods mousePressed() and mouseReleased() will help actually activating/deactivating DnD, the method mouseDragged() can be used to fix the icon at the mouse.

I hope this helps you creating your chess game, good luck!

  • Related