在 paintComponent() 中创建时,JTextField 出现在 2 个位置
JTextField appears in 2 locations when created inside paintComponent()
我正在创建一个扫雷游戏,我想要做的是有一个 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();
}
}
}
我认为问题在于您已经覆盖了 Board 中的 paintComponent class。每次需要绘制组件时都会调用此方法,因此每次都会添加一个新的文本字段。
最好在开发板的构造函数中添加文本字段 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 旨在与布局管理器一起使用。 JPanel 的默认布局管理器是 FlowLayout。 FlowLayout 将忽略 setBounds(...) 语句并根据 FlowLayout 的规则设置文本字段的 size/location。
所以不要尝试使用空布局,也不要使用 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 class 应该将 Board 的 getPreferredSize()
方法覆盖到 return 您想要的大小,以便 pack() 方法正常工作。
JFrame 的默认布局管理器是 BorderLayout
。因此,现在框架的顶部将包含居中的文本字段,框架的主要部分将包含您的 Board class。阅读 How to Use BorderLayout 上的 Swing 教程部分,了解上述代码的工作原理。
此外,MouseListener 应该添加到 Board,而不是 JFrame。
我正在创建一个扫雷游戏,我想要做的是有一个 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();
}
}
}
我认为问题在于您已经覆盖了 Board 中的 paintComponent class。每次需要绘制组件时都会调用此方法,因此每次都会添加一个新的文本字段。
最好在开发板的构造函数中添加文本字段 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 旨在与布局管理器一起使用。 JPanel 的默认布局管理器是 FlowLayout。 FlowLayout 将忽略 setBounds(...) 语句并根据 FlowLayout 的规则设置文本字段的 size/location。
所以不要尝试使用空布局,也不要使用 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 class 应该将 Board 的 getPreferredSize()
方法覆盖到 return 您想要的大小,以便 pack() 方法正常工作。
JFrame 的默认布局管理器是 BorderLayout
。因此,现在框架的顶部将包含居中的文本字段,框架的主要部分将包含您的 Board class。阅读 How to Use BorderLayout 上的 Swing 教程部分,了解上述代码的工作原理。
此外,MouseListener 应该添加到 Board,而不是 JFrame。