【发布时间】:2019-03-19 04:23:13
【问题描述】:
我想在GridLayout 中添加 100 个按钮,我的代码可以工作,但有时它只添加一个按钮,如果我点击其他按钮所属的位置,我点击的按钮就会出现。
它完全随机发生,我不明白。
这是我的代码:
public class GamePanel extends JPanel {
GameUI controler;
GridLayout gameLayout = new GridLayout(10,10);
JButton gameButtons[] = new JButton[100];
ImageIcon ice;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
URL urlIcon;
private int i;
public GamePanel(GameUI controler) {
this.setLayout(gameLayout);
this.controler = controler;
urlIcon = this.getClass().getResource("/icons/Overlay.png");
ice = new ImageIcon(urlIcon);
makeButtons();
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
public void makeButtons() {
for(i = 0; i< 100; i++) {
gameButtons[i] = new JButton(ice);
this.add(gameButtons[i]);
revalidate();
}
repaint();
}
}
更新:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;
public class GameUI extends JFrame {
ImageIcon i;
Image jFrameBackground;
JButton startButton;
JButton exitButton;
ImageIcon startIcon;
ImageIcon exitIcon;
public GameUI() {
setResizable(false);
this.setSize(1200, 800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(null);
BackGroundPanel backGroundPanel = new BackGroundPanel();
GamePanel panel = new GamePanel(this);
ButtonPanel buttonPanel = new ButtonPanel();
panel.setSize(500,500);
panel.setLocation(100, 150);
backGroundPanel.setSize(this.getWidth(),this.getHeight());
backGroundPanel.setLocation(0,0);
buttonPanel.setSize(390,50);
buttonPanel.setLocation(100,100);
this.add(backGroundPanel);
this.add(panel);
this.add(buttonPanel);
backGroundPanel.setBackground(Color.BLACK);
}
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
javax.swing.SwingUtilities.invokeAndWait(
new Runnable(){
@Override
public void run() {
GameUI ui = new GameUI();
ui.setVisible(true);
}
}
);
}
}
【问题讨论】:
-
您发布的代码不包含minimal reproducible example,我们可以编译、运行和测试的代码,包括一个主要方法,所以我不得不猜测。 也许你在别处得到了不恰当地调用超级的绘画方法的绘画代码。 也许在添加所有组件并在其上调用
setVisible(true)之后,您不会在顶级窗口(通常是 JFrame)上调用pack()。请注意,您需要在 for 循环之后调用revalidate(),而不是在其中调用,尽管这不会解决您的问题。 -
旁注 2:您几乎永远不会想要覆盖 JPanel 的
paint(...)方法,而是想要覆盖paintComponent(...)尽管这在这里无关紧要,因为您的绘制方法正在执行什么都没有。 -
旁注 3:您不会希望您的 GUI 类实现您的侦听器接口,因为这会给类带来太多责任——请阅读“single-responsibility principle”。我已从您发布的代码中删除了
implements...声明,因为它与您的问题无关,但我觉得有必要传递我认为对您未来代码很重要的建议。同样,请考虑改进这个问题和您发布的代码,以便它实际上是可以回答的,而无需我们进行猜测。 -
所以我添加了创建 jpanel 的位置,希望对您有所帮助。无论如何,游戏面板类不是 gui 类,按钮应该是“沉船”的游戏元素。如果我在paint方法中添加按钮,它不会与paintComponent一起使用。我试图添加 pack() 但它不起作用它只是将我的 jframe 缩小到最小。
-
1) 组件应在框架可见之前添加到框架中 2) 不需要 revalidate() 和 repaint(),因为面板尚未添加到框架中。您只需在将组件添加到可见 GUI 之后调用这些方法。但是在您的情况下,代码是从构造函数执行的,因此不需要它们。
标签: java swing panel layout-manager grid-layout