我正在为简单的battlships克隆设计一个简单的GUI。我曾经使用彩绘方块做过类似的事情,但决定尝试使用JPanels。除了顶部的标签(1-14)之外,这里的所有内容都按照我的意图运行。它已显示在1到4之间的任何地方,但从未全部显示为14,并且似乎有些随机显示了多少。应运行此代码,以便轻松查看问题。打印语句只是为了确认值是正确的。谢谢你的帮助!
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Foo {
private JFrame frame;
private JPanel[][] opponentBoard;
private JLabel[] coordLabels;
private final int FRAME_HEIGHT = 800;
private final int FRAME_WIDTH = 600;
private final int SQ_SIZE = 30;
public Foo() {
frame = new JFrame();
frame.setBounds(new Rectangle(FRAME_WIDTH, FRAME_HEIGHT));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.RED); // for debugging porpoises
frame.setLayout(null);
Container container = frame.getContentPane();
container.setBackground(Color.BLACK);
container.setVisible(true);
opponentBoard = new JPanel[15][11];
coordLabels = new JLabel[24];
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 11; j++) {
opponentBoard[i][j] = new JPanel();
container.add(opponentBoard[i][j]);
opponentBoard[i][j].setLocation(i + i * SQ_SIZE, j + j * SQ_SIZE);
opponentBoard[i][j].setSize(new Dimension(SQ_SIZE, SQ_SIZE));
opponentBoard[i][j].setVisible(true);
if ((i == 0) ^ (j == 0)) {
opponentBoard[i][j].setBackground(Color.GRAY);
if (i == 0) {
coordLabels[j - 1] = new JLabel((char) (j + 64) + "");
opponentBoard[i][j].add(coordLabels[j - 1]);
System.out.println(j-1);
}
if (j == 0) {
coordLabels[i + 9] = new JLabel(i + "");
System.out.println(i + 9 + " " + i + " " + coordLabels[i + 9].getText());
opponentBoard[i][j].add(coordLabels[i + 9]);
}
opponentBoard[i][j].repaint();
} else {
opponentBoard[i][j].setBackground(Color.DARK_GRAY);
}
}
}
opponentBoard[0][0].setBackground(Color.BLACK);
}
public static void main(String[] args){
new Foo();
}
}
答案 0 :(得分:4)
在将所有面板添加到容器后,您需要调用container.validate()
。另外,我会删除内部for循环中对repaint()
的调用。
或者,在添加面板之前,您无法将框架设置为可见;这表现得更好。
您可以在此处找到代码的工作版本:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Foo {
private JFrame frame;
private JPanel[][] opponentBoard;
private JLabel[] coordLabels;
private final int FRAME_HEIGHT = 800;
private final int FRAME_WIDTH = 600;
private final int SQ_SIZE = 30;
public Foo() {
frame = new JFrame();
frame.setBounds(new Rectangle(FRAME_WIDTH, FRAME_HEIGHT));
//frame.setVisible(true); Build the UI before making it visible
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.RED); // for debugging porpoises
frame.setLayout(null);
Container container = frame.getContentPane();
container.setBackground(Color.BLACK);
container.setVisible(true);
opponentBoard = new JPanel[15][11];
coordLabels = new JLabel[24];
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 11; j++) {
opponentBoard[i][j] = new JPanel();
container.add(opponentBoard[i][j]);
opponentBoard[i][j].setLocation(i + i * SQ_SIZE, j + j * SQ_SIZE);
opponentBoard[i][j].setSize(new Dimension(SQ_SIZE, SQ_SIZE));
opponentBoard[i][j].setVisible(true);
if ((i == 0) ^ (j == 0)) {
opponentBoard[i][j].setBackground(Color.GRAY);
if (i == 0) {
coordLabels[j - 1] = new JLabel((char) (j + 64) + "");
opponentBoard[i][j].add(coordLabels[j - 1]);
System.out.println(j-1);
}
if (j == 0) {
coordLabels[i + 9] = new JLabel(i + "");
System.out.println(i + 9 + " " + i + " " + coordLabels[i + 9].getText());
opponentBoard[i][j].add(coordLabels[i + 9]);
}
//opponentBoard[i][j].repaint();
} else {
opponentBoard[i][j].setBackground(Color.DARK_GRAY);
}
}
}
opponentBoard[0][0].setBackground(Color.BLACK);
// If the UI is already visible call validate
// I've chose to not make the frame visible until all of the children
// have been added so the call to validate isn't really needed.
//container.validate();
frame.setVisible(true);
}
public static void main(String[] args){
new Foo();
}
}