簡體   English   中英

Java:為什么在 for 循環外設置的變量會在 for 循環內發生變化

[英]Java: Why would a variable set outside of a for loop change inside of the for loop

我是一個相當新的程序員,正在 java 開發游戲(作為副項目)。 我學到了很多東西,而且我已經成功地在不需要幫助的情況下創造了數量驚人的游戲。 我什至可以省略這個 function,它不會破壞美感!

我想讓它工作,但我很困惑。 我在 for 循環之外設置了 tempColor 變量,但它在 for 循環內部發生了變化......但只有第二次激活它,並且只更改為第一次運行時使用的變量。 例如:如果我更改紅隊得分,它會運行並且我的 JOption 顯示紅色 - 紅色匹配並且它僅更改紅隊得分。 如果我然后更改藍隊得分,它會運行,找到藍色 - 藍色匹配更改分數,然后再次返回循環,直到找到紅色 - 紅色“匹配”並將該分數更改為與藍色分數。

我從頭到尾都在研究它,但找不到導致這種情況的原因。 我希望有人會可憐我並幫助我學習一些東西。

另一個我不明白的動作,我有一個主要的 class 變量 Choice,但它沒有傳遞到內部代碼中,所以我不得不將它傳遞給 tempColor 變量。 我還注意到我不能在方法內部重置它(關於需要是“最終的”。我認為這是因為它是一個臨時變量,在循環執行后不應該存在,但考慮到程序的行為......我不確定這是否重要,但認為它可能相關。

操作從菜單項開始:

private void mniAdjustScoreActionPerformed(java.awt.event.ActionEvent evt) {  
adjustScore();
}  

哪個運行:


    private void adjustScore() {
        //FIXME changing the first team AND the second team's score when called a second time for some unknown reason... an unexpected loop?
        //set components visibility
        df.CT.lblChoose.setText("Which team needs adjustment?");
        setCTButtons();
        df.CT.setVisible(true);
        df.CT.btnAdjust.setVisible(false);
        df.CT.jspAdjust.setVisible(false);
        df.CT.txtName.setVisible(false);
        
        //Set Choice color by button and pass to changeScore method
        df.CT.btnRedTeam.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Choice = "red";
                changeScore();
                Choice = "";
            }
        });
        
        df.CT.btnBlueTeam.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Choice = "blue";
                changeScore();
                Choice = "";
            }
        });
        df.CT.btnCyanTeam.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Choice = "cyan";
                changeScore();
                Choice = "";
            }
        });
        df.CT.btnYellowTeam.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Choice = "yellow";
                changeScore();
                Choice = "";
            }
        });
        df.CT.btnGreenTeam.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Choice = "green";
                changeScore();
                Choice = "";
            }
        });
        df.CT.btnPurpleTeam.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Choice = "purple";
                changeScore();
                Choice = "";
            }
        });
    }

按下按鈕后,它會運行 changeScore() 方法:


private void changeScore(){

        //TODO Fix me - running adjust score a second time changes both the second team and the first team. some kind of unintended loop???

        //set components visibilty for second part of operation
        df.CT.lblChoose.setVisible(true);
        df.CT.jspAdjust.setVisible(true);
        df.CT.btnAdjust.setVisible(true);
        df.CT.txtName.setVisible(false);
        
        //set tempColor to Choice value (LOOK UP LATER - not sure why this is necessary)
        String tempColor = Choice;
        
        //adjust button 
        df.CT.btnAdjust.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                //get value from spinner and assign to tempScore
                int tempScore = (Integer) df.CT.jspAdjust.getValue();

                //iterate through the teams to find the one whose TeamColor property matches tempColor
                for(int i=0; i<df.orderedTeamList.size(); i++){
                    String tempColor2 = df.orderedTeamList.getElementAt(i).getTeamColor();

                    //REMOVELATER - option pane to show values in each iteration
                    JOptionPane.showMessageDialog(null, "Choice: "+ Choice + "\n tempColor: " + tempColor + "\n tempScore: " + tempScore + "\n tempColor2: " + tempColor2,
                        "NOTE", JOptionPane.ERROR_MESSAGE);
                   
                    // look for a color match and assign values to the correct team
                    if (tempColor2.equals(tempColor)){
                        if (tempColor.equals("red")){
                            df.txtScoreT1.setBackground(Color.RED);
                 
                            df.orderedTeamList.getElementAt(i).setTeamScore(tempScore);
                        }
                        else if (tempColor.equals("blue")){
                            df.txtScoreT2.setBackground(Color.RED);
                            df.orderedTeamList.getElementAt(i).setTeamScore(tempScore);
                        }
                        else if (tempColor.equals("cyan")){
                            df.txtScoreT3.setBackground(Color.RED);
                            df.orderedTeamList.getElementAt(i).setTeamScore(tempScore);
                        }
                        else if (tempColor.equals("yellow")){
                            df.txtScoreT4.setBackground(Color.RED);
                            df.orderedTeamList.getElementAt(i).setTeamScore(tempScore);
                        }
                        else if (tempColor.equals("green")){
                            df.txtScoreT5.setBackground(Color.RED);
                            df.orderedTeamList.getElementAt(i).setTeamScore(tempScore);
                        }
                        else if (tempColor.equals("purple")){
                            df.txtScoreT6.setBackground(Color.RED);
                            df.orderedTeamList.getElementAt(i).setTeamScore(tempScore);
                        }
                        else{
                            JOptionPane.showMessageDialog(null, "Team is not active!",
                                "Team Error", JOptionPane.ERROR_MESSAGE);
                        }
                    }
                }
            // refresh point totals and close the CT window
            updatePoints();
            df.CT.setVisible(false);
            }
        });
    }

我最初試圖設置一個 joption 對話框來獲取此信息,但我無法讀取它。 然后我嘗試將顏色傳遞到方法中,但它產生了我現在遇到的相同效果......好吧,當我以這種方式設置它時,它並沒有改變分數。 這看起來很奇怪而且不合邏輯。

我添加了 joption 窗格來跟蹤變量,這就是我找到它在哪里以及在做什么的方式。 我只是不知道如何處理這些信息!

另外,我知道我的代碼沒有達到應有的效率。 我仍在學習和應用新技術。 我大約 2 個月前才開始在 java 工作,所以我的策略是讓它工作然后改進它。

不要動態地將ActionListener添加到您的按鈕 - 在創建組件時添加一次。

發生的事情是這樣的:

  • 你點擊紅隊的按鈕。 這會將Choice設置為“紅色”並調用changeScore()
  • changeScore()ActionListener添加到具有“紅色”的tempColor的調整按鈕
  • 你點擊按鈕來調整球隊的得分。 先前為紅隊添加的ActionListener運行並調整其分數。
  • 你點擊藍隊的按鈕。 這會將Choice設置為“blue”並調用changeScore()
  • changeScore()將第二個ActionListener添加到調整按鈕, tempColor為“藍色”
  • 你點擊按鈕來調整球隊的得分。 您添加的兩個ActionListener (一個用於藍隊,一個用於紅隊)運行並調整其團隊的得分。

如果您要單擊“青色”團隊的按鈕,您可以添加第三個ActionListener ,這將改變三個團隊的分數。

這個修復是——正如我在第一段中所寫的:不要動態地將ActionListener添加到您的按鈕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM