当前位置: 首页 > 知识库问答 >
问题:

我的setter不会初始化我的属性,我的属性总是等于零

呼延学
2023-03-14

我不知道为什么“选中”总是发送0值。我想发送在MainMenuSuperviser中选择的属性中由onItemSelected接收的值,但它不起作用,我不知道为什么。。。

我试图创建另一个对象,但没有帮助请帮助

package kingdomino.supervisers;

import java.util.*;

public final class MainMenuSuperviser extends Superviser {

    private int selected;
    public static final String QUIT = "Quitter";
    public static final String NEW_4_PLAYERS = "Jouer à 4";
    public static final String NEW_3_PLAYERS = "Jouer à 3";
    public static final String NEW_2_PLAYERS = "Jouer à 2";

    private MainMenuView view;

    public MainMenuSuperviser() {
    }

    public void setSelected(int selected) {
        this.selected = selected;
    }

    public void setView(MainMenuView view) {
        // TODO : définir les items à afficher par la vue
        this.view = view;
        view.setItems(List.of(NEW_2_PLAYERS, NEW_3_PLAYERS, NEW_4_PLAYERS, QUIT));
    }

    public void onItemSelected(int selected) {
        // TODO : réagir à l'événement utilisateur item sélectionné
        this.setSelected(selected);
        if ((selected == 0) || (selected == 1) || (selected == 2)) {
            this.selected = selected;
            view.goTo("PlayGame");
        }
        if (selected == 3)
            System.exit(0);
    }

    public int getSelected() {
        return selected;
    }

}

然后是程序部分,启动代码的部分

public class Program {
    private final static List<Domino> dominoes = CsvDataReader.readDominoesFromFile("resources/data/dominoes.csv").stream()
            .map(dto -> new Domino(dto.getId(), 
                    new Tile(Terrain.valueOf(dto.getTerrain1()), dto.getCrownsCount1()),
                    new Tile(Terrain.valueOf(dto.getTerrain2()), dto.getCrownsCount2())))
            .collect(Collectors.toList());
    
    private final static List<Player> players = CsvDataReader.readPlayersFromFile("resources/data/players.csv").stream()
            .map(dto -> new Player(dto.getName(), dto.getHexColor()))
            .collect(Collectors.toList());
    
    /**
     * Point d'entrée d'une exécution.
     * L'application ne tient pas compte des arguments.
     * 
     * @param args une liste d'arguments. 
     */
    public static void main(String[] args) {
        
        MainMenuSuperviser mSuperviser = new MainMenuSuperviser();
        GameFactory gF = new GameFactory(mSuperviser.getSelected(), players, dominoes);
        NewGame nG = new NewGame(gF.getSelected(), gF.getListDominoes(), gF.getListPlayers());
        Game game = new Game(players, nG.getPile(), nG.getSelected());

        PlayGameSuperviser superviser = new PlayGameSuperviser(game);
        
        MainWindow window = new MainWindow("Ai 2022 - KingDomino - Lawson Jefferson",
            new SwingMainMenuView("MainMenu", mSuperviser),
            new SwingPlayGameView("PlayGame", superviser, mSuperviser.getSelected())
        );
        window.start("MainMenu");
    }

}

然后这里是onItemSelected被调用的地方

public final class SwingMainMenuView extends SwingView implements MainMenuView {
    private static final long serialVersionUID = -2211970715714357966L;
    private final ImageIcon background = new ImageIcon("resources/images/main_menu_background.jpg");
    private final MainMenuSuperviser superviser;
    
    private List<String> items; 
    private int selected = 0;
    
    public SwingMainMenuView(String title, MainMenuSuperviser superviser) {
        super(title);
        this.superviser = superviser;
        this.superviser.setView(this);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);    
        drawBackground(g);
        drawCommands(g);
        drawMenuItems(g);
    }

    private void drawCommands(Graphics g) {
        int left = Theme.PANEL_WIDTH/100*2;
        int top = Theme.PANEL_HEIGHT/100*3;
        
        g.setColor(new Color(255,255,255,128));
        g.fillRect(left-5, top-11, 200, 62);
        g.setColor(Color.BLACK);
        
        g.drawString("\u2191 : déplacer vers le haut",left, top);
        g.drawString("\u2193 : déplacer vers le bas",left, top+20);
        g.drawString("\u23ce : choisir",left, top+40);
        
    }

    private void drawBackground(Graphics g) {
        g.drawImage(background.getImage(), 0, 0, null);
    }
    
    private void drawMenuItems(Graphics g) {
        int left = Theme.PANEL_WIDTH/3;
        int top = Theme.PANEL_HEIGHT/3;
        int width = Theme.PANEL_WIDTH/3;
        int height = Theme.PANEL_HEIGHT/12;
        int gap = Theme.PANEL_HEIGHT/15;
        
        
        for(int i=0; i < items.size(); ++i) {
            var item = items.get(i);
            
            if(i == selected) {
                g.setColor(Theme.SECONDARY_BACKGROUND_COLOR_ALPHA);
                g.fillRoundRect(left - gap/2, top - gap/2, width + gap, height + gap, gap, gap);
                
                g.setColor(Theme.SECONDARY_BACKGROUND_COLOR);
                g.drawRoundRect(left - gap/2, top - gap/2, width + gap, height + gap, gap, gap);
            }
            
            g.setColor(Theme.SECONDARY_BACKGROUND_COLOR);
            g.fillRoundRect(left, top, width, height, 5, 5);
            
            g.setFont(Theme.ITEM_FONT);
            g.setColor(Theme.PRIMARY_COLOR);
            g.drawString(item, left+gap/2, top+height/2);       
            
            top += gap + height;
        }
        
    }

    @Override
    public void onKeyTyped(int keyCode) {
        if(keyCode == KeyEvent.VK_DOWN) {
            this.selected = (selected + 1) % items.size();
        } else if(keyCode == KeyEvent.VK_UP) {
            this.selected = (selected == 0) ? items.size() - 1 : selected - 1;
        } else if(KeyEvent.VK_ENTER == keyCode) {
            this.superviser.onItemSelected(this.selected);
        }
        
        this.repaint();
    }

    @Override
    public void setItems(List<String> items) {
        this.items = List.copyOf(items);
        this.selected = 0;
        this.repaint();
    }

}

共有1个答案

韩羽
2023-03-14

我不会回答所问的问题,所以原谅我,但是你的问题并不是一个可以简单回答的形式。请参阅关于最小可复制示例的评论。

但是,总的来说,编程的很大一部分是测试和调试。学习成为Java程序员的一个基本部分是学习行业工具。测试和调试通常比一开始编写程序需要更长的时间。没关系。

解决此类问题的最佳方法是单独测试每个位,然后构建测试交互,然后在执行时测试或观察整个事情。

  1. 为似乎属于问题的每个组件的每个元素编写单元测试。使用JUnit或其他选择

作为最简单的单元测试,实例化一个MainMenuSuperviser,并将其selected属性设置为多个不同的值,获取值并比较您设置的值是否与您获得的值相同。对于简单的getter和setter,您根本不需要编写单元测试——但这是第一步。

然后调用已知值为selectedonItemSelected方法,查看您得到的值是否与之匹配。请注意,如果使用值3调用它,测试将无法完成!

使用JUnit或类似的方法意味着您为功能的各个方面或至少为您需要调查的每个错误构建了一套可复制的测试。在每个构建周期中运行这些测试。修复任何损坏的问题。

实例化一个MainMenuSuperviser,然后实例化一个SwingMainMenuView,并将视图提供给主管。模拟调用onKeyTyped(…) keyCode值编码>并检查所选的值是否符合预期。您可能需要添加一个get方法来允许测试。

然后,做同样的事情,并在supervisor中测试selected的值。

使用模拟框架来测试更复杂的交互。

随着时间的推移,先学会设计测试,然后再开发功能代码。

使用调试器附加到正在运行的代码。使用断点、监视变量,并在调用代码时逐步遍历代码。密切关注所选变量的值。

在代码运行时,使用日志框架(例如log4j或替代方案)记录方法调用和变量值<代码>系统。出来println可以作为一个非常快速的

 类似资料:
  • 我不知道为什么“选中”总是发送0值。我想发送onItemSelected在MainMenuSuperviser中选择的属性中收到的值,但它不起作用,我不知道为什么。 我试图创建另一个对象,但没有帮助。 然后是程序部分,启动代码的部分 这就是调用onItemSelected的地方

  • 问题内容: 我有一个Swift类,我想看起来像这样: 但是,Swift不喜欢我要传递给初始化程序的事实。我在这里打破某些模式吗?应该如何完成这样的初始化? 问题答案: 您已经找到了Implicitly Unwrapped Optional 的主要用例。 你需要访问的,之前被初始化。 否则,应该 永远 是零,所以你不应该有外部的检查。 因此,您应该声明。

  • 问题内容: 您将如何在Swift中实现以下模式? 所述类被初始化,其中包含的词典JSON数组。这些字典用于初始化类。但是,当访问或属性时,对象的初始化会延迟进行。 问题答案: 看来这个问题已经得到了很大的回答,但是回过头来看原始帖子,这是(IMHO)Swift中相对简洁的翻译。关键是您可以链接惰性属性。请注意,我同时使用了类函数和闭包- 两者都很好。

  • 这肯定是个愚蠢的问题,但我对Kotlin真的是个新手,我没有找到任何解决办法。 如何声明类字段?就像我们可以在Java中拥有它一样: 在中: 但我得到一个警告:“属性必须初始化或抽象”

  • 我在想,是否可以使用对< code>this关键字的引用来初始化一个(引用类型)属性(当它的值为< code>null),而不使用构造函数。< br >在某些情况下,我不想使用构造函数来初始化属性,因此,如果没有人访问它,它的值将不会被创建。< br >此外,如果可能的话,我不喜欢在构造函数中将属性声明与其初始化分开。 一个典型的例子是MVVM模式编程的命令声明: 我不喜欢写三倍的成员的名字… 我

  • 问题内容: 我在HTML中创建了一个属性,该属性动态地填充了信息。 有没有一种方法可以检测属性值何时更改? 问题答案: 您将必须注意DOM节点的更改。有一个名为的API,但似乎对其的支持非常有限。这样的答案有一个指向API状态的链接,但是到目前为止,似乎在IE或Opera中都不支持它。 解决该问题的一种方法是让修改属性的代码部分分派一个您可以侦听的事件。 这里的代码是