Swing:在我将鼠标悬停在组件上之前,组件不会消失
Swing: Component wont dissapear until I hover over the component
我正在 java swing 中开发一个小游戏作为一个小型学校项目。我完成了所有逻辑和 GUI。
游戏(Snakes and Stairs) 有 36 个方块 (JButtons),每个方块内部都有 Jpanel,可用于将玩家棋子放在 (JButtons)。换句话说,我有 36 个按钮,里面都有 Jpanel,所有 JPanel 都可以驻留按钮。在每个方块上,我都放置了一个动作侦听器,用于检查轮到谁,玩家是否可以移动到这里,并且仅当这些条件(当然还有更多)为真时,才将玩家按钮移动到该方块。
现在是越野车部分。当玩家棋子移动时,它会出现在新方格 和旧方格 上。如果我将鼠标悬停在它上面,它只会从旧方块上消失。
一些可能有助于理解的代码:
//this happens in another function. I only show this, because i think this is the only part relevant from the function
spots[i][j].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//EventQueue.invokeLater(()->setGameSpotsAction(f,p,spotNr));
setGameSpotsAction(f,p,spotNr);
}
});
//action to do when a spot/square is pressed
public void setGameSpotsAction(JFrame f, JPanel p, int nr) {//nr is the spot where the piece should go
if(nr == X*Y && playerPosition[playerTurn] + latestRoll == nr){//if dice is rolled
f.remove(p);
winnerwinnerchickendinner.setText(namesArr[playerTurn]+" WON!!!!!!");
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx=0;gbc.gridy=0;panel.add(winnerwinnerchickendinner,gbc);
f.getContentPane().add(panel);
} else if (latestRoll >= 2 && nr <= X*Y && playerPosition[playerTurn] + latestRoll == nr) {//
int sot = snakeOrStairs[playerPosition[playerTurn] + latestRoll];//sot stands for Snake Or sTair
//if just regular square/spot
if(playerPosition[1] != playerPosition[2]){//if player moves and the previous spot is empty, make panel invisible.
spotPanels[playerPosition[playerTurn]].setVisible(false);
}
if (sot == 0) {
playerPosition[playerTurn] += latestRoll;//button has new position
movePlayerButton(nr);
//EventQueue.invokeLater(()->{movePlayerButton(nr);});
} else if (sot > 0) {//if positive number, we can go up!!
playerPosition[playerTurn] += latestRoll + sot;//button has new position
movePlayerButton(nr + sot);
//EventQueue.invokeLater(()->{movePlayerButton(nr);});
} else {//god damn it we going down
playerPosition[playerTurn] += latestRoll - sot;//button has new position
movePlayerButton(nr - sot);
//EventQueue.invokeLater(()->{movePlayerButton(nr);});
}
changePlayerTurn(diceLabelText[1], diceLabelText[2]);
roll.setEnabled(true);//next player can now roll
}
}
public void movePlayerButton(int spotNr){
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx=0;gbc.gridy=playerTurn-1;
spotPanels[spotNr].add(playerButtons[playerTurn],gbc);//move players button to the new spot
spotPanels[spotNr].setVisible(true);//set the panel to visible
}
我试过的:
- 我尝试在每次棋子移动后调用“frame.pack()”。它似乎在第一次调用时工作,但之后框架开始表现得很奇怪。(我至少尝试了一些......)
- 我试过 EventQueue.InvokeLater 和 EventQueue.invokeAndWait。这很可能不起作用,因为我真的不知道如何正确使用它。 java.awt.EventQueue.invokeLater explained
当更改容器中包含的组件(正确使用布局管理器的组件)时,您始终应该在容器或其父容器之一上调用 revalidate()
,因为这会告诉布局管理器和管理器任何嵌套容器 re-layout 它们的组件。您还经常需要在容器上调用 repaint()
以请求重新绘制它及其子项,主要是清除任何潜在的 left-over 脏像素。从容器中移除组件时尤其如此。
我正在 java swing 中开发一个小游戏作为一个小型学校项目。我完成了所有逻辑和 GUI。
游戏(Snakes and Stairs) 有 36 个方块 (JButtons),每个方块内部都有 Jpanel,可用于将玩家棋子放在 (JButtons)。换句话说,我有 36 个按钮,里面都有 Jpanel,所有 JPanel 都可以驻留按钮。在每个方块上,我都放置了一个动作侦听器,用于检查轮到谁,玩家是否可以移动到这里,并且仅当这些条件(当然还有更多)为真时,才将玩家按钮移动到该方块。
现在是越野车部分。当玩家棋子移动时,它会出现在新方格 和旧方格 上。如果我将鼠标悬停在它上面,它只会从旧方块上消失。
一些可能有助于理解的代码:
//this happens in another function. I only show this, because i think this is the only part relevant from the function
spots[i][j].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//EventQueue.invokeLater(()->setGameSpotsAction(f,p,spotNr));
setGameSpotsAction(f,p,spotNr);
}
});
//action to do when a spot/square is pressed
public void setGameSpotsAction(JFrame f, JPanel p, int nr) {//nr is the spot where the piece should go
if(nr == X*Y && playerPosition[playerTurn] + latestRoll == nr){//if dice is rolled
f.remove(p);
winnerwinnerchickendinner.setText(namesArr[playerTurn]+" WON!!!!!!");
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx=0;gbc.gridy=0;panel.add(winnerwinnerchickendinner,gbc);
f.getContentPane().add(panel);
} else if (latestRoll >= 2 && nr <= X*Y && playerPosition[playerTurn] + latestRoll == nr) {//
int sot = snakeOrStairs[playerPosition[playerTurn] + latestRoll];//sot stands for Snake Or sTair
//if just regular square/spot
if(playerPosition[1] != playerPosition[2]){//if player moves and the previous spot is empty, make panel invisible.
spotPanels[playerPosition[playerTurn]].setVisible(false);
}
if (sot == 0) {
playerPosition[playerTurn] += latestRoll;//button has new position
movePlayerButton(nr);
//EventQueue.invokeLater(()->{movePlayerButton(nr);});
} else if (sot > 0) {//if positive number, we can go up!!
playerPosition[playerTurn] += latestRoll + sot;//button has new position
movePlayerButton(nr + sot);
//EventQueue.invokeLater(()->{movePlayerButton(nr);});
} else {//god damn it we going down
playerPosition[playerTurn] += latestRoll - sot;//button has new position
movePlayerButton(nr - sot);
//EventQueue.invokeLater(()->{movePlayerButton(nr);});
}
changePlayerTurn(diceLabelText[1], diceLabelText[2]);
roll.setEnabled(true);//next player can now roll
}
}
public void movePlayerButton(int spotNr){
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx=0;gbc.gridy=playerTurn-1;
spotPanels[spotNr].add(playerButtons[playerTurn],gbc);//move players button to the new spot
spotPanels[spotNr].setVisible(true);//set the panel to visible
}
我试过的:
- 我尝试在每次棋子移动后调用“frame.pack()”。它似乎在第一次调用时工作,但之后框架开始表现得很奇怪。(我至少尝试了一些......)
- 我试过 EventQueue.InvokeLater 和 EventQueue.invokeAndWait。这很可能不起作用,因为我真的不知道如何正确使用它。 java.awt.EventQueue.invokeLater explained
当更改容器中包含的组件(正确使用布局管理器的组件)时,您始终应该在容器或其父容器之一上调用 revalidate()
,因为这会告诉布局管理器和管理器任何嵌套容器 re-layout 它们的组件。您还经常需要在容器上调用 repaint()
以请求重新绘制它及其子项,主要是清除任何潜在的 left-over 脏像素。从容器中移除组件时尤其如此。