作者obelisk0114 (追风筝的孩子)
看板java
标题[问题] inner class 没有执行
时间Fri Dec 11 22:28:23 2015
我的程式是一个可以计时的记忆翻牌游戏
在程式一些方法中建立一个新的 timer 并呼叫相应的 timertask
我的 timertask 以 inner class 写在相同的 class 里面
奇怪的是那方法就只有 timer & timertask 没有执行,其他都顺利执行
我怀疑是我用了 2个 timertask 做不同事情而没有另外新增执行绪
以下为部分程式码,请各位大大看看哪边出问题,若资讯太少会在补充
谢谢
private JFrame mainFrame;
...
private List<JButton> Cards = new ArrayList<JButton>();
private List<Integer> numberlist = new ArrayList<Integer>();
private int firstOpenCard = -1; // 记录第一次翻开的牌
private int openCards = -1; // 记录翻开几组
private Timer timer, timer2; // timer2 用来设定翻错的牌多久盖回,没有顺利执行
private int i1;
public MemoryGame(String title) {
playerTable = new JPanel();
playerArea = new JPanel();
playerInformation = new JPanel();
...
mainFrame = new JFrame(title);
playerInformation.add(clicks);
playerInformation.add(time);
clickDetermine clickCards = new clickDetermine(); //替每个按钮加上事件
startBtn = new JButton("start");
startBtn.addActionListener(
new ActionListener () {
public void actionPerformed(ActionEvent arg0) {
if ( (openCards != CardNumber/2) && (openCards != -1) ) {
timer.cancel();
int option = JOptionPane.showConfirmDialog(null,
"Do you want to restart the game ?", "Confirm",
JOptionPane.YES_NO_CANCEL_OPTION);
if (option == 1 || option == 2) {
timer = new Timer();
timer.schedule(new timeDisplay(), 0, 1000);
return;
}
}
...
timer = new Timer();
timer.schedule(new timeDisplay(), 0, 1000);
}
});
giveUpBtn = new JButton("give up");
giveUpBtn.addActionListener(...);
...
private class clickDetermine implements ActionListener {
public void actionPerformed(ActionEvent e) {
useSteps++;
for (int i = 0 ; i < CardNumber ; i++) {
if (e.getSource() == Cards.get(i)) {
// 翻的是第一张, 记录位置
if (firstOpenCard == -1) {
Cards.get(i).setText(numberlist.get(i) + "");
firstOpenCard = i;
clicks.setText("目前翻动次数 : " + useSteps);
}
else {
if (i == firstOpenCard) { // 翻同一张
useSteps--;
return;
}
Cards.get(i).setText(String.valueOf(numberlist.get(i)));
clicks.setText("目前翻动次数 : " + useSteps);
// 翻对
if (numberlist.get(i).equals(numberlist.get(firstOpenCard))) {
Cards.get(i).setEnabled(false);
Cards.get(firstOpenCard).setEnabled(false);
openCards++;
if (openCards == CardNumber/2) { // 翻完,停止计时
timer.cancel();
}
}
else { // 翻错
i1 = i;
timer2 = new Timer();
timer2.schedule(new coverback(), 1500);
timer2.cancel();
}
firstOpenCard = -1;
}
break;
}
}
}
}
...
private class timeDisplay extends TimerTask { // 设定时间显示
public void run() { ...
}
}
private class coverback extends TimerTask { // 设定将牌盖回
public void run() {
Cards.get(firstOpenCard).setText("*");
Cards.get(i1).setText("*");
}
}
...
--
肝不好 ▁▁ ● ◤
肝若好
人生是黑白的 ▏ ◤
考卷是空白的
▏ ◤
、 ﹐
● ●b 囧 ▎ ●> ● ◤
▌ ﹍﹍ 0 ▊囧>
干...
▲ ■┘ ■ ▎ ■ █◤ ▌ ㄏ▋ ︶■
〈﹀ ∥ ▁▁∥ ▎ ﹀〉◤
▋ ▊ 〈\
ψcockroach727
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.112.232.118
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1449844111.A.A57.html
1F:推 AI3767: 翻错 那边, 一schedule完就cancel不会有问题吗? 12/11 23:11
中间若要插入 sleep ,数值设定太小也不会执行
设大一些要冻结很久,而且也不会有翻开又盖回的感觉
※ 编辑: obelisk0114 (140.112.232.118), 12/12/2015 00:34:35
2F:→ AI3767: 不清楚你的timer2还有做什麽其它的, 如果不cancel可以吗? 12/12 00:44
3F:→ AI3767: 另外是,这里没看到clickCards变数有被谁用 12/12 00:46
timer2 是设定盖回去的时间,只有将2张翻开的牌盖回去
我有试过将 timer2.cancel() 删掉,执行会报错误
clickCards 是设定 16 张牌的 ActionPerformed, 相关程式码附上如下
for (int i = 0 ; i < CardNumber ; i++) { // CardNumber 是总共有几张牌
numberlist.add(new Integer(i/2 + 1));
Cards.add(new JButton("*"));
playerArea.add(Cards.get(i));
Cards.get(i).addActionListener(clickCards);
}
※ 编辑: obelisk0114 (140.112.232.118), 12/12/2015 01:56:24
4F:→ AI3767: 呃 是报什麽错?? 12/12 16:37
原本觉得他的报错很奇怪
後来 print 出来发现翻错那边
在跑到 timer2 = new Timer(); 会因为後面的 firstOpenCard = -1;
而将 firstOpenCard 设定成 -1,这样 coverback 的
Cards.get(firstOpenCard).setText("*");
就会因为抓到 Cards.get(-1) 而出错
不知道为何 ?
※ 编辑: obelisk0114 (140.112.232.118), 12/12/2015 18:30:13
5F:→ jinn: timer2.cancel()删掉 然後coverback那里改成 12/12 21:10
6F:→ jinn: if(firstOpenCard!=-1) { 12/12 21:11
7F:→ jinn: Cards.get(firstOpenCard).setText("*"); } 12/12 21:12
8F:→ jinn: 不就好了@@? 12/12 21:13
Cards.get(firstOpenCard).setText("*");
是翻错时,把第一张翻开的牌盖回去
若移到上面会变成翻错时,先将第一张盖回,1.5秒後盖回第二张
感觉很奇怪
※ 编辑: obelisk0114 (140.112.232.118), 12/12/2015 21:19:58
9F:推 AI3767: 这个报错和timer无关, 是程式逻辑要修, 你的写法,遇到连续 12/12 22:11
10F:→ AI3767: 开牌, 可能也会有问题 12/12 22:11
程式逻辑要修可以多提一下吗 ?
资讯太少,不知道怎麽改
timer 和 timertask 的搭配好像是另一个执行绪
是因为主要程式执行完才会交给 timer2 和 coverback ?
虽然只要多定义一个变数,将 firstOpenCard 传入,再由 coverback 接收就好
※ 编辑: obelisk0114 (140.112.232.118), 12/13/2015 02:57:46
11F:→ AI3767: 上面这句, 这样做是好的, 在new coverback时传入谁要翻回 12/13 23:46
12F:→ AI3767: timer new一次就够了. 然後连续翻牌问题, 可以有两种方法 12/13 23:47
13F:→ AI3767: 1:最多翻两张, 两张有中,或是两张都翻回後, 才能翻下一轮 12/13 23:48
14F:→ AI3767: 2:可连续翻牌,但自己定出方法和资料结构, 能记得哪两张要 12/13 23:50
15F:→ AI3767: 互相配对比较 12/13 23:50
只用滑鼠点击好像不会达成连续翻牌 ?
记得哪2张的方式像是下面吗 ?
在 public class MemoryGame{
private int i1,i2; // 在 clickDetermine 才传入第一张,第二张
}
※ 编辑: obelisk0114 (140.112.232.118), 12/14/2015 02:27:47
16F:→ AI3767: 也可以,原先的firstOpenCard也可以,只要能确保一次最多只 12/14 22:11
17F:→ AI3767: 会翻开两张. 然後程式执行的部份再检查看看吧 12/14 22:15