在paintComponent()中创建时,JTextField出现在两个位置

时间:2019-06-06 12:47:03

标签: java swing jtextfield minesweeper

我正在创建一个扫雷游戏,我想要做的是拥有一个JTextField,用户可以在其中输入他的名字,以便将其分数保存在文件中。

我的问题是,当我创建JTextField并将其添加到Jpanel时,它会出现在2个位置。这是正在发生的事情的图像 (https://i.imgur.com/Ao8dRo1.jpg

这是我的代码过于简化。我相信我对GUI的工作原理不了解。

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();
        }
    }

}

2 个答案:

答案 0 :(得分:2)

我认为问题是您在Board类中重写了paintComponent。每次需要绘制组件时都会调用此方法,因此每次都会添加一个新的文本字段。

最好在董事会类的构造函数中添加文本字段。

答案 1 :(得分:2)

  

我使用命令textField.setBounds(290,80,135,40);将其放置在我想要的位置,但不起作用。为什么会发生这种情况?

Swing旨在与布局管理器一起使用。 JPanel的默认布局管理器是FlowLayout。 FlowLayout将忽略setBounds(...)语句,并根据FlowLayout的规则设置文本字段的大小/位置。

因此,请勿尝试使用空布局,也不要使用setBounds()。而是让布局管理器完成其工作。

此外,在使框架可见之前,应将组件添加到框架中。

我建议您的代码应类似于:

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 );

Board类应重写Board的getPreferredSize()方法以返回所需的大小,以便pack()方法正常工作。

JFrame的默认布局管理器是BorderLayout。因此,现在框架的顶部将包含居中的文本字段,框架的主要部分将包含Board类。阅读How to Use BorderLayout的Swing教程中的部分,以了解上述代码的工作原理。

此外,应将MouseListener添加到开发板,而不是JFrame。