看板 java 關於我們 聯絡資訊
※ 引述《tatibana31 (橘三十一)》之銘言: : 以下是類似的程式碼: : public void procedure() : { : if(computer){ : Action_A(); Action_B(); Drawing(); : computer = false; : procedure(); : }else if(!computer){ : Action_A(); mouseControl = true; : } : } : 滑鼠的程式碼為: : public void mouseClicked(mouseEvent m) : { : if(mouseControll){ : Action_B(); Drawing(); mouseControll = false; : computer = true; : procedure(); : } : } : 大概就是玩牌時那種輪流的狀況,我現在遇到一個問題, : 如果我只click 一次的話,什麼問題都沒有(這應該是正常的) : 但是如果我連續狂按十次的話,procedure會連跑十次,即使有mouseControl這個 : 變數去控制的話,也是一樣 : 這種情形我該怎麼作,才有辦法在取得下次滑鼠控制權之前,只接受一次click,其 : 它視為無效? : 我試過 : 用Thread.sleep()....無效。 : 用add & removeMouseListener()....無效 : 在procedure前加一個單次迴圈....無效 : 加synchronized好像在此是沒有作用的.... : 懇請有空的人,可以告訴我該怎麼作才可以作到?非常感謝! 剛剛手滑,重要的反而沒貼上來.... add & removeMouseListener() 是有效的,問題是在這兩者實際生效的時間點並非立即 的,所以才會有明明已經 removeMouseListener 但是該聽取者卻又收的到事件的怪事。 解決的方法仍然是 Multi-threading 目標是想辦法在重要的工作進行的過程中,接收 到滑鼠事件直接略過並丟棄。 注意:呼叫 mouseClicked 方法的執行緒只有一個: AWTThread 所以不用想競速條件的問題,在此問題下,使用 synchronized 語法是不必要的。 以下是我的解決辦法: mouseAdapter = new MouseAdapter() { public void mouseClicked(MouseEvent event) { // 判斷事件是否已啟用 if (eventAvailable) { // 停用事件 eventAvailable = false; // 移除滑鼠聽取者 myComponent.removeMouseListener(mouseAdapter); // 跑重要的工作 (說明一) new Thread(task).start(); } } }; task = new Runnable() { public void run() { // TODO 在這邊寫下你的程式碼 // 加回滑鼠聽取者 myComponent.addMouseListener(mouseAdapter); // 啟用事件 eventAvailable = true; } }; 說明一:改寫成 task.run() 是錯誤的,原因是 AWTThread 在做完 task 之後會去拿取 新的事件,此時 eventAvailable 是 true,且滑鼠聽取者已被加回去。只有 new Thread(task).start() 或類似方法讓 AWTThread 離開萬惡的 mouseClicked 方法,趕 快拿取新的事件,趁 task 還沒做完,快速地略過並丟棄新的事件。 如果 Component 提供的 getMouseListener()[0] 能協助判斷的話,請將 eventAvailable 移除,並且換成 getMouseListener()[0] 相關的控制方式,以減少不 必要的控制變數。 我已經寫好一份範例,如果需要的話,請來信通知。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.127.39.76
H45:getMouseListeners()[0] 01/08 04:24
tatibana31:超級感謝,不過我從沒寫過這種,可能需要想一下,剛剛 01/08 07:36
tatibana31:失眠時,想到一種寫法,待會兒比較有精神時再來試試 01/08 07:40
superlubu:大推 01/08 09:55
TonyQ:我這篇也有一些相關的參考資料 #17MwHw0E (java) 01/08 14:45