我正在创建一个扫雷游戏,我想要做的是拥有一个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();
}
}
}
答案 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。