Java Swing:直到我将鼠标悬停在组件上,组件才会消失

Java Swing:直到我将鼠标悬停在组件上,组件才会消失,java,swing,actionlistener,awt-eventqueue,Java,Swing,Actionlistener,Awt Eventqueue,我正在用JavaSwing开发一个小游戏,作为学校的一个小项目。我已经完成了所有的逻辑和GUI 游戏(蛇和楼梯)有36个方块(JButtons),每个方块内都有JPanel,可以用来放置玩家的棋子(JButtons)。换句话说,我有36个按钮,里面都有JPanel,所有JPanel都可以驻留在按钮中。在每个方块上,我都放置了一个动作监听器,检查轮到谁了,玩家是否可以移动到这里,并且只有在这些条件(当然还有更多条件)为真的情况下,才会将玩家按钮移动到那个方块上 现在是马车部分。当一个棋子移动时,它

我正在用JavaSwing开发一个小游戏,作为学校的一个小项目。我已经完成了所有的逻辑和GUI

游戏(蛇和楼梯)有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
    }
//这在另一个函数中发生。我只展示这个,因为我认为这是函数中唯一相关的部分
spots[i][j].addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
//invokeLater(()->setGameSpotsAction(f,p,spotNr));
设置配子点集(f、p、spotNr);
}
});
//按下点/正方形时要执行的操作
public void setGameSpotsAction(JFrame f,JPanel p,int nr){//nr是该作品应该去的地方
如果(nr==X*Y&&playerPosition[playerTurn]+latewalk==nr){//如果掷骰子
f、 移除(p);
winnerwinnerchickendinner.setText(namesArr[playerTurn]+“WON!!!!!!!”;
JPanel panel=newjpanel(newgridbagloayout());
GridBagConstraints gbc=新的GridBagConstraints();
gbc.gridx=0;gbc.gridy=0;panel.add(WinnerWinnerWinnerChickendInner,gbc);
f、 getContentPane().add(面板);
}else if(latewalk>=2&&nr{movePlayerButton(nr);});
}否则如果(sot>0){//如果是正数,我们可以上升!!
playerPosition[playerTurn]+=latewalk+sot;//按钮具有新位置
移动播放按钮(nr+sot);
//invokeLater(()->{movePlayerButton(nr);});
}否则{//该死的,我们就要倒下了
playerPosition[playerTurn]+=latewalk-sot;//按钮具有新位置
移动播放按钮(nr-sot);
//invokeLater(()->{movePlayerButton(nr);});
}
changePlayerTurn(DicelLabelText[1],DicelLabelText[2]);
roll.setEnabled(真)//下一个玩家现在可以掷骰子了
}
}
公共无效移动播放按钮(int spotNr){
GridBagConstraints gbc=新的GridBagConstraints();
gbc.gridx=0;gbc.gridy=playerTurn-1;
spotPanels[spotNr].add(playerButtons[playerTurn],gbc);//将玩家按钮移动到新位置
spotPanels[spotNr].setVisible(true);//将面板设置为visible
}
我尝试过的:

  • 我尝试在每次工件移动后调用“frame.pack()”。第一次调用它时,它似乎起作用,但在那之后,帧开始动作异常(我至少尝试了一些东西…)
  • 我已经尝试了EventQueue.InvokeLater和EventQueue.invokeAndWait。这很可能不起作用,因为我真的不知道如何正确使用它
当更改容器中保存的组件(正确使用布局管理器的容器)时,始终应在容器或其父容器之一上调用
revalidate()
,因为这将告诉布局管理器和任何嵌套容器的管理器重新布局其组件。您还经常需要在容器上调用
repaint()
,请求对容器及其子容器进行重新绘制,主要是为了清除任何可能留下的脏像素。从容器中移除组件时,后一种情况尤其如此。

在更改组件内容后,您似乎没有在容器(JPanel)上调用
revalidate()
repaint()
。我建议你在ActionListeners的结尾做这个。第一个告诉布局管理器中继组件,第二个清除任何可能遗留的脏像素。如果这不能解决问题,那么考虑用你的问题发布一个有效的。这是有效的。如果你把答案贴在下面,我会把它作为正确答案。