摇摆:在我将鼠标悬停在组件上之前,组件不会消失

问题描述

我正在作为小型学校项目开发Java Swing中的小型游戏。我已经完成了所有逻辑和GUI。

游戏(“蛇和楼梯”)有36个方格(JButton),每个方格内都有Jpanel,可用于将玩家放置在(JButtons)处。换句话说,我有36个按钮,所有按钮内部都包含Jpanel,并且所有JPanels都可以驻留按钮。在每个广场上,我都放置了一个动作侦听器,以检查玩家是否可以移动到此处,然后仅在满足这些条件(当然还有更多条件)的情况下,将玩家按钮移动到该广场上。

现在是越野车的一部分。当玩家一块移动时,它会出现在新方块上。如果我将鼠标悬停在旧广场上,它只会消失在旧广场上。

一些可能有助于理解的代码

//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,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(),因为这将告诉布局管理器和管理器任何嵌套容器以重新布局其组件。您通常还希望在容器上调用repaint(),以请求对其容器及其子级进行重新粉刷,主要是清除所有可能残留的脏像素。当从容器中取出组件时,后者尤其如此。