Java Swing练习 - 无法访问变量,不知道为什么

时间:2011-02-22 15:56:02

标签: java

我正在学习Java开发和家庭作业,我被指示使用Swing框架编写基本应用程序代码。设置非常简单:一个应用程序从卡片组(Arraylist)中选择两张卡片(字符串),让用户猜测第二张卡片是高于还是低于第一张卡片。

一块蛋糕,对吧?所以我也想过,直到我偶然发现一个问题:我已经将一个动作链接到一个按钮,并且动作确实被执行了,但我似乎无法访问我在处理动作时在我的应用程序中启动的变量。看一下“Gok hoger”动作,它会为“kaart1”返回一个空值。然而,当我在我的程序构造函数中回显字符串“kaart1”时,它被填写得很好。我对这个原因一无所知......所以我希望这里的一些聪明人能够向我解释为什么我的代码会像这样。

if(e.getActionCommand().equals("Gok hoger")){
    System.out.println(kaart1); // <------- Why does this return null?
}

是的,这是一项家庭作业,我已将其标记为以防万一。

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.*;
import java.awt.Dimension;

public class Programma extends JFrame {

    ArrayList<String> kaartboek = new ArrayList<String>();
    boolean gewonnen = false;
    int kaart1waarde;
    int kaart2waarde;
    String kaart1;
    String kaart2;

    public Programma(){
        super("Hoger/lager");

        vulKaartboek(kaartboek);
        String kaart1 = new String(trekKaart(kaartboek));
        String kaart2 = new String(trekKaart(kaartboek));

        JButton hogerButton = new JButton("Hoger");
        JButton lagerButton = new JButton("Lager");
        hogerButton.setAction(new Actie("Gok hoger"));
        lagerButton.setAction(new Actie("Gok lager"));

        JLabel kaart1label = new JLabel(new ImageIcon(
            "/Users/David/Dropbox/School/eclipse/2011/VGO_Opdracht1/src/kaartboek/"
            + kaart1 +".png"));
        JLabel kaart2label = new JLabel(new ImageIcon(
            "/Users/David/Dropbox/School/eclipse/2011/VGO_Opdracht1/src/kaartboek/"
            + "back" + ".png"));

        Container c = getContentPane();
        c.setLayout(new GridLayout(2,2));
        c.add(kaart1label);
        c.add(kaart2label);
        c.add(hogerButton);
        c.add(lagerButton);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }

    public static void main (String args[]){
        JFrame frame1 = new Programma();
    }

    public String getKaartSuit(String kaart){
        String kaart1suit = kaart.substring(0, 1);
        if(kaart1suit.equals("c")){kaart1suit = "Klaveren";}
        if(kaart1suit.equals("d")){kaart1suit = "Ruiten";}
        if(kaart1suit.equals("h")){kaart1suit = "Harten";}
        if(kaart1suit.equals("s")){kaart1suit = "Schoppen";}
        return kaart1suit;
    }

    public String getKaartBeeld(String kaart){
        int kaartwaarde = Integer.parseInt(kaart.substring(1, kaart.length()));
        String kaartbeeld = "";
        switch(kaartwaarde){
            case 2: kaartbeeld = "Twee"; break;
            case 3: kaartbeeld = "Drie"; break;
            case 4: kaartbeeld = "Vier"; break;
            case 5: kaartbeeld = "Vijf"; break;
            case 6: kaartbeeld = "Zes"; break;
            case 7: kaartbeeld = "Zeven"; break;
            case 8: kaartbeeld = "Acht"; break;
            case 9: kaartbeeld = "Negen"; break;
            case 10: kaartbeeld = "Tien"; break;
            case 11: kaartbeeld = "Boer"; break;
            case 12: kaartbeeld = "Dame"; break;
            case 13: kaartbeeld = "Heer"; break;
            case 14: kaartbeeld = "Aas"; break;
        }
        return kaartbeeld;
    }

    public String getKaartNaam(String kaart){
        String kaartnaam = getKaartSuit(kaart) + " " + getKaartBeeld(kaart);
        return kaartnaam;
    }

    public String trekKaart(ArrayList<String> kaartboek){
        Random random = new Random();
        int willekeurig = random.nextInt(kaartboek.size());

        String kaart = kaartboek.get(willekeurig);
        kaartboek.remove(willekeurig);

        return kaart;
    }

    public void vulKaartboek(ArrayList kaartboek){
        for(int i = 2; i < 14; i++){
            kaartboek.add("c" + i); // Clubs
            kaartboek.add("d" + i); // Diamonds
            kaartboek.add("h" + i); // Hearts
            kaartboek.add("s" + i); // Spades
        }
    }

    public int getKaartWaarde(String kaart){
        int kaartwaarde = Integer.parseInt(kaart.substring(1, kaart.length()));
        return kaartwaarde;
    }

    class Actie extends AbstractAction  { // Inner klasse
        public Actie(String s){
            super(s); 
        }
        public void actionPerformed(ActionEvent e) {
            if(e.getActionCommand().equals("Gok hoger")){
                System.out.println(kaart1); // <------- Why does this return null?

                }
            if(e.getActionCommand().equals("Gok lager")){
                System.out.println("Test");
            }
        } 
    }
}

5 个答案:

答案 0 :(得分:4)

你有两个名为kaart1的变量。一个是Programma构造函数的本地。在“Actie”中访问的是实例变量。

您可能不打算在构造函数中声明第二个变量,而是初始化实例变量。替换“String kaart1 = new String(trekKaart(kaartboek));”用“kaart1 = new String(trekKaart(kaartboek));”

答案 1 :(得分:1)

你得到null因为你在这里使用局部变量:

    String kaart1 = new String(trekKaart(kaartboek));

替换为

    this.kaart1 = new String(trekKaart(kaartboek));

答案 2 :(得分:1)

正如其他人所说,问题围绕着Hiding Fields。另外,考虑编程到界面:

List<String> kaartboek = new ArrayList<String>();

trekKaart()中,不要重复实例化Random()。而是一次洗牌:

Collections.shuffle(kaartboek);

然后,您可以使用更简单的trekKaart()

轻松检索随机卡片
kaart1 = trekKaart(kaartboek, 1);
kaart2 = trekKaart(kaartboek, 2);

private String trekKaart(List<String> kaartboek, int index) {
    return kaartboek.get(index);
}

最后,trekKaart()vulKaartboek()Programma构造函数调用,因此它们应该是私有的。

答案 3 :(得分:0)

在构造函数中,您声明了两个新的kaart对象。内部类正在尝试访问未分配的旧kaart变量,因此为“null”

String kaart1;
String kaart2;

public Programma(){
    super("Hoger/lager");

    vulKaartboek(kaartboek);
    String kaart1 = new String(trekKaart(kaartboek)); // You shoud initialize it as this.kaart1
    String kaart2 = new String(trekKaart(kaartboek)); // You shoud initialize it as this.kaart2

}

答案 4 :(得分:-2)

变量kaart1未在Actie类中声明。这就是为什么它是null。你的代码很难为我阅读(部分是你的语言部分设计),所以我不知道你想要做什么。