英文:
java GUI multiple buttons output display error?
问题
我是Java的初学者。这是我的第一个项目。
代码的图形用户界面每次运行代码时都在不断变化。
有时输出甚至没有完全加载。
这是一个只初始化8x8棋盘按钮的代码。
我已经放下了图片,请查看下面的超链接。
有没有什么解决方案可以在每次执行代码时都显示相同的输出?
package chess;
import game.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
public class board{
static JButton [][] spots =new JButton [8][8];
public static void main(String[] args){
board b =new board();
b.initializeboard(spots);
}
public void initializeboard(JButton [][] spots){
JFrame f = new JFrame("CHESS");
f.setVisible(true);
f.setSize(800,800);
GridLayout layout =new GridLayout(8,8,1,1);
f.setLayout(layout);
for(int ver=0;ver<8;ver++){
for(int hor=0;hor<8;hor++){
JButton button = new JButton();
if((ver+hor)%2==0){
button.setBackground(Color.WHITE); }
else{
button.setBackground(new Color(255,205,51)); }
pieces p =new pieces();
spots[ver][hor] = button;
p.setButton(button);
f.add(button);
}
}
} //initialize board
} // close board
[执行不当][1]
[正确执行][2]
[执行不完整][3]
[1]: https://i.stack.imgur.com/vDsS5.png
[2]: https://i.stack.imgur.com/vwZBe.png
[3]: https://i.stack.imgur.com/dXECk.png
英文:
I am beginner in Java. This is my first project.
The GUI of the code keeps changing every time I run the code.
Sometimes output doesn't even load completely.
This is the code for just initializing a chess board 8X8 jbuttons.
I have put down the images do checkout the hyperlinks below.
Is there any solution that shows the same output every time the code executes?
package chess;
import game.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.*;
public class board{
static JButton [][] spots =new JButton [8][8];
public static void main(String[] args){
board b =new board();
b.initializeboard(spots);
}
public void initializeboard(JButton [][] spots){
JFrame f = new JFrame("CHESS");
f.setVisible(true);
f.setSize(800,800);
GridLayout layout =new GridLayout(8,8,1,1);
f.setLayout(layout);
for(int ver=0;ver<8;ver++){
for(int hor=0;hor<8;hor++){
JButton button = new JButton();
if((ver+hor)%2==0){
button.setBackground(Color.WHITE); }
else{
button.setBackground(new Color(255,205,51)); }
pieces p =new pieces();
spots[ver][hor] = button;
p.setButton(button);
f.add(button);
}
}
} //initialize board
} // close board
答案1
得分: 1
> 我是Java的初学者。
首先,类名应该以大写字符开头。你有没有见过JDK中以小写字符开头的类?可以通过教材或教程中的代码示例进行学习。
> 有没有办法让代码每次执行时都显示相同的输出?
所有的组件都应该在窗口可见之前添加到框架中。当窗口变为可见时,布局管理器会被调用,并为组件设置大小/位置。如果你在一个可见的面板上添加组件,那么你需要在面板上调用 revalidate()
和 repaint()
方法,以确保布局管理器被调用。
必须承认我不太确定为什么会出现这种随机行为。一些组件正在获得大小/位置,而其他组件却没有,尽管布局管理器没有被调用。
我建议你重新构造你的代码,类似这样:
JPanel chessboard = new JPanel(new GridLayout(8, 8, 1, 1));
// 添加按钮到面板
JFrame frame = new JFrame("CHESS");
frame.add(chessboard, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
其他评论:
- 不要设置窗口的大小。使用 800 x 800 并不会使每个按钮都变成 100 x 100。窗口的大小还包括标题栏和边框,所以每个按钮的大小会小于你的预期。
相反,你可以在循环外创建一个变量:
Dimension buttonSize = new Dimension(100, 100);
然后在创建按钮时使用:
button.setPreferredSize(buttonSize);
现在,当调用 pack()
方法时,它会将窗口的大小设置为所有添加到窗口中的组件的首选大小。
-
所有的Swing组件都应该在“事件分派线程(EDT)”上创建。阅读Swing教程中的“How to Make Frames”部分。
FrameDemo.java
代码向你展示了一种在类中结构化代码的方法,以确保代码在EDT上执行。 -
不要将变量设置为静态的。这表明类设计不正确。在“How to Use Menus”中的
MenuLook.java
示例中,展示了稍微不同的设计方式,其中你的ChessBoard
变成了在另一个类中创建的组件。然后,你可以在那个类中定义你的实例变量。
英文:
> I am beginner in Java.
First of all, class names SHOULD start with an upper case character. Have you even seen a class in the JDK that does not start with an upper case character? Learn by example from the code in your text book or tutorial.
> Is there any solution that shows the same output every time the code executes?
All components should be added to the frame BEFORE the frame is made visible.
When the frame is made visible the layout manager is invoked and the components are given a size/location. If you add components to a visible panel, then you need to invoke revalidate()
and repaint()
on the panel to make sure the layout manager is invoked.
Must admit I'm not sure why you get this random behaviour. Some components are getting a size/location and other are not even though the layout manager is not invoked.
I would suggest you restructure your code something like:
JPanel chessboard = new JPanel( new GridLayout(8, 8, 1, 1) );
// add buttons to the panel
JFrame frame = new JFrame("CHESS")
frame.add(chessboard, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
Other comments:
- Don't set the size of the frame. Using 800 x 800 will not make each button 100 x 100. The frame size also include the title bar and borders, so each button size will be less than you expect.
Instead you can create a variable outside of your loops:
Dimension buttonSize = new Dimension(100, 100)
Then when you create the button you use:
button.setPreferredSize( buttonSize );
Now when pack() method is invoked is will size the frame at the preferred size of all the components added to the frame.
-
All Swing components should be create on the
Event Dispatch Thread (EDT)
. Read the section from the Swing tutorial How to Make Frames. TheFrameDemo.java
code shows you one way to structure your class so that theinvokeLater(…)
method is used to make sure code executes on the EDT. -
Don't make your variables static. This indicates incorrect class design. Check out the
MenuLook.java
example found in How to Use Menus for a slightly different design where yourChessBoard
becomes a component created in another class. You can then define your instance variables in that class.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论