【问题标题】:Putting JButtons on a stack将 JButton 放在堆栈上
【发布时间】:2014-03-04 07:03:10
【问题描述】:

我正在制作一个统计数据保存程序来练习我在 Java 中的 GUI 技能。

我有一个程序可以通过点击篮球运动员姓名下的 JButton 来记录他们的统计数据。然后它将统计数据添加到运行总数中并更新记分牌。

现在是时候创建一个撤消按钮了。

因此,每次执行操作时,我都会将源按钮添加到 JButton 堆栈中。涉及到一些演员,所以它最终是这样的:

JButton source = (JButton) e.getSource();
theStack.push(source);

稍后,在actionPerformed 方法中,我尝试通过撤消函数调用:

if(source.getText().equals("Undo")){
    System.out.println("Undo");
    JButton last = this.theStack.pop();
    System.out.println(last.getText()); //Works fine.
    System.out.println(last.getName()); //Produces a null value.
    int player = Integer.parseInt(last.getName().trim());
    undo(player, last.getText(), activePlayers);
}

为什么我的名字是空的。 Eclipse 在尝试将名称转换为 int 时抛出异常,因为它正在转换空值。我在actionPerformed的其他部分使用.getName(),但这里没有?

我的名字设置代码,在for循环中做了很多次。

output[i][j] = new JButton("Make Two Points");
output[i][j].setName(i + "");

问题的最简单形式。

public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        ArrayList<Integer> activePlayers = new ArrayList<Integer>();
        activePlayers.add(player0Select.getSelectedIndex());
        activePlayers.add(player1Select.getSelectedIndex());
        activePlayers.add(player2Select.getSelectedIndex());
        activePlayers.add(player3Select.getSelectedIndex());
        activePlayers.add(player4Select.getSelectedIndex());

        JButton source = (JButton) e.getSource();
        theStack.push(source);

        if(source.getText().equals("Make Two Points")){
            this.makeTwoPoints(source.getName(), activePlayers); //source.getName() works here.
            System.out.println("Two Points");
        }
        if(source.getText().equals("Undo")){
            System.out.println("Undo");
            JButton last = this.theStack.pop();
            System.out.println(last.getText());
            System.out.println(last.getName()); //last.getName() produces null here.
            int player = Integer.parseInt(last.getName().trim());
            undo(player, last.getText(), activePlayers);
        }
}

【问题讨论】:

    标签: java null stack jbutton undo


    【解决方案1】:

    因为您从不设置 JButton 的 名称,也不应该设置。每个组件都有一个可以通过setName(...) 方法设置的名称属性,如果从未调用过setter 方法,则该名称为空。但是这个属性有什么意义呢?这里不多。

    如果这是我的项目,我不会堆叠 JButton,而是堆叠模型对象,或者可能是控件(动作)。我们不要将模型与视图混在一起。


    编辑

    举个简单的例子来说明我的意思,

    您可以拥有一个包含您的三个(或更多统计操作)的 StatAction 枚举,例如,

    public enum StatAction {
       MAKE_2_PTS("Make Two Points"), MISS_2_PTS("Miss Two Points"), 
       MAKE_3_PTS("Make Three Points");
    
       private String text;
    
       private StatAction(String text) {
          this.text = text;
       }
    
       @Override
       public String toString() {
         return text;
       }
    
       public String getText() {
          return text;
       }
    
    }
    

    你可以有一个 Player 类,它可以包含一个名称字段以及一个 List&lt;StatAction&gt;,例如它可以有...

    public class Player {
       private String name;
       private List<StatAction> statActionList = new ArrayList<>();
    
       // ....
    
       public String getName() {
          return name;
       }
    
       public void addStatAction(StatAction statAction) {
          statActionList.add(statAction);
       }
    
       public void removeStatAction(StatAction statAction) {
          statActionList.remove(statAction);
       }
    
       public void removeLastStatAction() {
          if (statActionList.size() > 0) {
             statActionList.remove(statActionList.size() - 1);
          }
       }
    
       //.....
    
    }
    

    然后撤消可以从玩家列表中删除最后一个 StatAction。然后可以通过侦听器即时更改统计信息的显示。

    【讨论】:

    • 我在生成它们时确实设置了它们,名称对应于列号,它将它与我程序中的活跃玩家联系起来。
    • @TrevorHutto:JVM 会告诉你不然,我相信 JVM。请出示您的设置代码。
    • @TrevorHutto:您需要创建并发布一个可测试的mcve,以便我们能够完全理解您的问题。
    • @TrevorHutto:嗯,...请重新阅读mcve link 或第一次阅读它,因为您还没有发布任何接近其中的内容。
    • 你缺少哪一部分?
    猜你喜欢
    • 1970-01-01
    • 2011-10-07
    • 2015-07-26
    • 2013-05-03
    • 1970-01-01
    • 2015-08-13
    • 2018-06-01
    • 1970-01-01
    • 2021-09-09
    相关资源
    最近更新 更多