Search code examples
javaswingjtextfieldminesweeper

JTextField appears in 2 locations when created inside paintComponent()


I am creating a minesweeper game, and what I want to do is to have a JTextField where the user inputs his name in order for his score to be saved in a file.

My problem is that when I create a JTextField and add it to my Jpanel it appears in 2 locations. Here is an image of what is happening (https://i.sstatic.net/6fUtJ.jpg)

This is my code over-simplified. I believe that I don't properly understand something about how the mechanism of the GUI works.

GUI.java

public class GUI extends JFrame {
  //..
  //some variables here
  //...

  public GUI() {
        this.setTitle("Minesweeper Game");
        this.setSize(WIDTH, HEIGHT);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setResizable(false);
        this.setLayout(null);

        //This method does not involve any drawing, it only places data in some arrays that I later use in paintComponent() to draw stuff accordingly to what the data is
        setMinefield();


        Board board = new Board();
        this.setContentPane(board);

        Click click = new Click();
        this.addMouseListener(click);
    }

    public class Board extends JPanel {
        public void paintComponent (Graphics g) {
        //...    
        //Drawing tiles, smiley, counters
        //...

        //And now I draw the area for the JTextField, and I also create it and add it in the Jpanel
        JTextField textField = new JTextField();
        textField.setFont(new Font("Tahoma", Font.PLAIN, 35));
        textField.setBounds(290, 80, 135, 40); //<-- This correctly places the textField where I want. The second textField seems to appear in the exact center of the X axis of my window

        add(textField); //<-- Adding the textField to the Jpanel

        } //End of paintComponent()
    }//End of Board class
}//End of GUI class

Main.java

public class Main implements Runnable {

    GUI gui = new GUI();

    public static void main(String[] args) {
        new Thread (new Main()).start();
    }

    @Override
    public void run() {
        while (true) {
            gui.repaint();
        }
    }

}

Solution

  • I think the problem is that you have overridden paintComponent in your Board class. This method gets called every time the component needs to be drawn so a new text field will be added each time.

    It would be better to add the text field in the constructor for your board class.