简体   繁体   中英

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.imgur.com/Ao8dRo1.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();
        }
    }

}

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.

I use the command textField.setBounds(290, 80, 135, 40); to place it where I want but it doesn't work. Why could this happen?

Swing was designed to used with layout managers. The default layout manager for a JPanel is the FlowLayout. The FlowLayout will ignore the setBounds(...) statement and set the size/location of the text field based on the rules of the FlowLayout.

So don't attempt to use a null layout and don't use setBounds(). Instead let the layout manager do its job.

Also, you should be adding the components to the frame BEFORE you make the frame visible.

I would suggest your code should be something like:

JTextField textField = new JTextField(10);
JPanel top = new JPanel();
top.add( textField );

Board board = new Board();

add(top, BorderLayout.PAGE_START);
add(board, BorderLayout.CENTER);
setResizable( false );
pack();
setVisible( true );

The Board class should override the getPreferredSize() method of the Board to return your desired size so that the pack() method works properly.

The default layout manager for a JFrame is the BorderLayout . So, now the top part of the frame will contain the text field centered and the main part of the frame will contain your Board class. Read the section from the Swing tutorial on How to Use BorderLayout to understand how the above code works.

Also, the MouseListener should be added to the Board, not the JFrame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM