在嵌套面板中移动标签
Moving labels in nested panels
我制作了两个网格并使用嵌套面板将它们添加到 window。唯一的问题是我无法移动中心的网格,也无法在各自的网格下获取标签。尝试使用 setBounds 但这不起作用。有什么建议吗?我添加了当前状态的图像。我想分别在第一格和第二格下显示玩家和对手标签。
public static void main(String[] args) {
window = new JFrame();
window.setTitle("Battleship.exe");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setPreferredSize(new Dimension(800, 800));
P1_container = new JPanel(new GridLayout(10,10));
P1_container.setPreferredSize(new Dimension(400, 400));
P1_container.setBorder(BorderFactory.createLineBorder(Color.black, 5));
compContainer = new JPanel(new GridLayout(10,10));
compContainer.setPreferredSize(new Dimension(400, 400));
compContainer.setBorder(BorderFactory.createLineBorder(Color.black, 5));
grid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
grid[i][j] = new JPanel();
grid[i][j].setBackground(Color.white);
grid[i][j].setBorder(BorderFactory.createLineBorder(Color.blue, 2));
grid[i][j].setPreferredSize(new Dimension(35,35));
P1_container.add(grid[i][j]);
}
}
enemyGrid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
enemyGrid[i][j] = new JPanel();
enemyGrid[i][j].setBackground(Color.lightGray);
enemyGrid[i][j].setBorder(BorderFactory.createLineBorder(Color.red, 2));
enemyGrid[i][j].setPreferredSize(new Dimension(35, 35));
compContainer.add(enemyGrid[i][j]);
}
}
GridLayout layout = new GridLayout(1, 2);
layout.setHgap(150);
mainPanel = new JPanel(layout);
mainPanel.add(P1_container);
mainPanel.add(compContainer);
player = new JLabel("PLAYER");
player.setBounds(100, 410, 5, 5);
opponent = new JLabel("OPPONENT");
opponent.setBounds(100, 410, 5, 5);
panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.add(mainPanel, BorderLayout.CENTER);
panel.add(player, BorderLayout.WEST);
panel.add(opponent, BorderLayout.WEST);
window.add(panel, BorderLayout.CENTER);
window.pack();
window.setVisible(true);
}
请标记您的 as solved if they are. People have taken the time to help you out and it's the least you can do. Read here for more information on What should I do when someone answers my question?
您仍在调用 setPreferredSize
,您应该覆盖 getPreferredSize
,并且仅在必要时覆盖。如果您的网格 JPanel
的大小是通过 getPreferredSize
调整的,则无需在它们各自的容器或 JFrame
上调用 setPreferredSize
,而且您仍然没有在EDT.
正如其他人提到的,您不能在使用 LayoutManager
时使用 setBounds
。要实现你想要的,你需要嵌套布局,正如你之前被告知的那样。
所以您可能想创建两个带有 BorderLayout 的 JPanel
。这两个新容器将分别容纳每个网格及其标签:
JPanel p1Container = new JPanel(new BorderLayout());
p1Container.add(P1_container, BorderLayout.CENTER);
p1Container.add(player, BorderLayout.SOUTH);
JPanel opponentContainer = new JPanel(new BorderLayout());
opponentContainer.add(compContainer, BorderLayout.CENTER);
opponentContainer.add(opponent, BorderLayout.SOUTH);
...
panel.add(p1Container);
panel.add(opponentContainer);
下面的代码也没有意义:
panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.add(mainPanel, BorderLayout.CENTER);
panel.add(player, BorderLayout.WEST);
panel.add(opponent, BorderLayout.WEST);
默认情况下,JPanel
使用 FlowLayout
,因此 BorderLayout.XXX
在这里没有任何意义。
再次花时间阅读 A Visual Guide to Layout Managers 但我展示的代码通过不将任何额外参数传递给 add()
来更正此问题
public static void main(String[] args) {
window = new JFrame();
window.setTitle("Battleship.exe");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setPreferredSize(new Dimension(800, 800));
P1_container = new JPanel(new GridLayout(10,10));
P1_container.setPreferredSize(new Dimension(400, 400));
P1_container.setBorder(BorderFactory.createLineBorder(Color.black, 5));
compContainer = new JPanel(new GridLayout(10,10));
compContainer.setPreferredSize(new Dimension(400, 400));
compContainer.setBorder(BorderFactory.createLineBorder(Color.black, 5));
grid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
grid[i][j] = new JPanel();
grid[i][j].setBackground(Color.white);
grid[i][j].setBorder(BorderFactory.createLineBorder(Color.blue, 2));
grid[i][j].setPreferredSize(new Dimension(35,35));
P1_container.add(grid[i][j]);
}
}
enemyGrid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
enemyGrid[i][j] = new JPanel();
enemyGrid[i][j].setBackground(Color.lightGray);
enemyGrid[i][j].setBorder(BorderFactory.createLineBorder(Color.red, 2));
enemyGrid[i][j].setPreferredSize(new Dimension(35, 35));
compContainer.add(enemyGrid[i][j]);
}
}
GridLayout layout = new GridLayout(1, 2);
layout.setHgap(150);
mainPanel = new JPanel(layout);
mainPanel.add(P1_container);
mainPanel.add(compContainer);
player = new JLabel("PLAYER");
player.setBounds(100, 410, 5, 5);
opponent = new JLabel("OPPONENT");
opponent.setBounds(100, 410, 5, 5);
panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.add(mainPanel, BorderLayout.CENTER);
panel.add(player, BorderLayout.WEST);
panel.add(opponent, BorderLayout.WEST);
window.add(panel, BorderLayout.CENTER);
window.pack();
window.setVisible(true);
}
请标记您的
您仍在调用 setPreferredSize
,您应该覆盖 getPreferredSize
,并且仅在必要时覆盖。如果您的网格 JPanel
的大小是通过 getPreferredSize
调整的,则无需在它们各自的容器或 JFrame
上调用 setPreferredSize
,而且您仍然没有在EDT.
正如其他人提到的,您不能在使用 LayoutManager
时使用 setBounds
。要实现你想要的,你需要嵌套布局,正如你之前被告知的那样。
所以您可能想创建两个带有 BorderLayout 的 JPanel
。这两个新容器将分别容纳每个网格及其标签:
JPanel p1Container = new JPanel(new BorderLayout());
p1Container.add(P1_container, BorderLayout.CENTER);
p1Container.add(player, BorderLayout.SOUTH);
JPanel opponentContainer = new JPanel(new BorderLayout());
opponentContainer.add(compContainer, BorderLayout.CENTER);
opponentContainer.add(opponent, BorderLayout.SOUTH);
...
panel.add(p1Container);
panel.add(opponentContainer);
下面的代码也没有意义:
panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.add(mainPanel, BorderLayout.CENTER);
panel.add(player, BorderLayout.WEST);
panel.add(opponent, BorderLayout.WEST);
默认情况下,JPanel
使用 FlowLayout
,因此 BorderLayout.XXX
在这里没有任何意义。
再次花时间阅读 A Visual Guide to Layout Managers 但我展示的代码通过不将任何额外参数传递给 add()