2014-02-07 61 views
1

我正在制作一个统计程序来练习我在Java中的GUI技能。将JButton放在堆栈上

我有一个程序,通过按下他们的名字打一个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); 
     } 
} 

回答

1

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

如果这是我的项目,我不会堆栈JButtons,而是堆叠模型对象,或者控件(Actions)。让我们不要将我们的模型与我们的观点混合。


编辑

对于我的意思一个简单的例子,

你可以有一个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; 
    } 

} 

你可以有一个播放器类,可以包括名称字段以及List<StatAction>,例如它可以有...

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。统计数据的显示可以通过侦听器实时更改。

+0

当我生成它们时,我确实设置了它们,该名称对应于列号,它将其转换为我的程序中的活动播放器。 –

+0

@TrevorHutto:JVM正在告诉你,否则我相信JVM。请显示您的设置代码。 –

+0

@TrevorHutto:您需要创建并发布可测试[mcve](http://stackoverflow.com/help/mcve),以便我们能够充分理解您的问题。 –