2012-12-14 18 views
6

मैं स्विंग करने के लिए नया हूं, किसी भी मदद की सराहना की।स्विंग घटकों को सही ढंग से अद्यतन कर रहा है?

कोड के इस टुकड़े में मैं चेहरे पर एक कार्ड बदल रहा हूं, अगर यह पता चला कि वे मेल नहीं खाते हैं तो मैं उन्हें फिर से चेहरे को वापस चालू करना चाहता हूं।

पल क्या हो रहा है पर: 1. जब क्लिक पहले कार्ड 2. से अधिक हो जाती है जब एक दूसरे कार्ड दो बातें या तो क्लिक किया जाता है पर हो (क) अगर वे एक ही कर रहे हैं वे दोनों रहते हैं जो मुझे (बी) यदि वे समान नहीं हैं तो मैं दूसरे कार्ड को कभी भी नहीं देखता क्योंकि यह तुरंत कार्ड के पीछे फिर से प्रदर्शित करता है (और पिछले कार्ड के पीछे भी मेरी विधि में परिभाषित किया गया है)।

मैंने सोचा कि नींद टाइमर डालने से दूसरे कार्ड को वापस चालू करने से पहले समय के लिए प्रदर्शित किया जा सकता है लेकिन ऐसा नहीं होता है।

मैंने contentPane.revalidate() का उपयोग करने का प्रयास किया; & contentPane.repaint(); लेकिन यह कुछ भी नहीं बदलता है।

मैं कुछ सांत्वना आउटपुट में डाल दिया है:

Console output: 
Card: 0 set 
Card: 6 set 
Sleeping now 
Card: 6 unset 
Card: 0 unset 

से ऊपर है जब दो कार्ड जो मेल नहीं खाते

@Override 
public void actionPerformed(ActionEvent e) 
{ 
    String buttonPressed = e.getActionCommand(); 
    int pos = Integer.valueOf(buttonPressed); 
    action = Control.model.ReceiveCardsTurned(pos); 

    keypadArray[pos].setIcon(myIcons[pos]);  
    System.out.println("Card: "+pos+" set"); 
    currentTime.setText("" + Control.model.time); 
    currentScore.setText("" + Control.model.score); 

    //contentPane.revalidate(); 
    //contentPane.repaint();   

    if(Control.model.twoCardsTurned == false) 
    { 
     if (action == "unturn") 
     { 
      System.out.println("Sleeping now"); 

      try 
      { 
       Thread.sleep(1000); 
      } 

      catch (InterruptedException e1) 
      { 
       e1.printStackTrace(); 
      } 

      keypadArray[pos].setIcon(back); 
      keypadArray[Control.model.lastCard].setIcon(back); 
      System.out.println("Card: "+pos+" unset"); 
      System.out.println("Card: "+Control.model.lastCard+" unset"); 
     } 
    } 
} 

उत्तर

6

ऐसी कई महत्वपूर्ण अवधारणाएं हैं जो आपको याद आ रही हैं।

  1. स्विंग एक घटना संचालित वातावरण है। इसका मतलब है कि उपयोगकर्ता इनपुट के लिए "प्रतीक्षा" करने का कोई मतलब नहीं है (या कम से कम केवल कुछ ही), आमतौर पर, आपको केवल अपनी बातचीत पर प्रतिक्रिया करने की आवश्यकता होती है।
  2. स्विंग को एक थ्रेड द्वारा संचालित किया जाता है, जिसे इवेंट डिस्पैचिंग थ्रेड (AKA EDT) कहा जाता है। आवेदन के उचित हिस्सों में आवेदन में आने वाली घटनाओं को प्रेषित/संसाधित करने के लिए इस धागे की ज़िम्मेदारी है ताकि वे कार्रवाई कर सकें।
  3. पुनर्विक्रेता प्रबंधक ईडीटी पर अपने अपडेट अनुरोध पोस्ट करता है।

कोई भी कार्रवाई जो आप इस काम को करने से ईडीटी को रोकती है, वह आपके आवेदन को लटकाएगी जैसा दिखता है।

ईडीटी पर आपको कभी भी उपभोग करने वाले संचालन (जैसे I/O, loops या Thread#sleep) को कभी भी नहीं लेना चाहिए, ऐसा करने से आपका एप्लिकेशन "रोकें", जो कभी भी सुंदर नहीं होगा।

अधिक जानकारी के लिए Concurrency in Swing के माध्यम से पढ़ा है।

अब, आपके पास कई विकल्प हैं। आप पृष्ठभूमि में "प्रतीक्षा" करने के लिए Thread का उपयोग कर सकते हैं और कार्ड को वापस चालू कर सकते हैं या आप SwingWorker या javax.swing.Timer का उपयोग कर सकते हैं।

आपके पास दूसरी समस्या यह है कि आपको ईडीटी के अलावा किसी भी Thread से किसी भी यूआई घटकों को अद्यतन नहीं करना चाहिए।इसका मतलब है कि यदि आप Thread का उपयोग करना चाहते थे, तो आप उस थ्रेड को ईडीटी के साथ फिर से सिंक करने के लिए ज़िम्मेदार बन जाएंगे। मुश्किल नहीं है, यह सिर्फ गन्दा हो जाता है।

SwingWorker और javax.swing.Timer कार्यक्षमता है जो इसे अधिक आसान बनाता है।

थ्रेड और SwingWorker पृष्ठभूमि प्रसंस्करण करने के लिए बहुत अच्छे हैं और इस समस्या के लिए बस अधिक हो जाएंगे। इसके बजाए, javax.swing.Timer पूरी तरह फिट होगा।

if (!Control.model.twoCardsTurned) 
    { 
     if ("unturn".equals(action)) 
     { 
      new Timer(1000, new ActionListener() { 
       public void actionPerformed(ActionEvent evt) { 
        keypadArray[pos].setIcon(back); 
        keypadArray[Control.model.lastCard].setIcon(back); 
        System.out.println("Card: "+pos+" unset"); 
        System.out.println("Card: "+Control.model.lastCard+" unset"); 
       } 
      }).start(); 
     } 
    } 

यह वास्तव में एक साधारण उदाहरण है। आप कुछ नियंत्रणों को रखना चाहेंगे जो उपयोगकर्ता को टाइमर आग तक कुछ भी क्लिक करने से रोक देगा, उदाहरण के लिए;)

+0

धन्यवाद, बहुत सहायक और बहुत ही जानकारीपूर्ण उत्तर। मुझे स्विंग की बुनियादी अवधारणाओं पर कुछ और पढ़ना होगा – Ron

7

आप घटना प्रेषण सूत्र में सो नहीं सकता पर क्लिक जिसके परिणामस्वरूप कंसोल आउटपुट है , क्योंकि आपका जीयूआई स्थिर हो जाएगा। आपको Swing Timer का उपयोग करना होगा। पृष्ठभूमि कार्यों के लिए आपको भविष्य में चिंता करने की ज़रूरत होगी, SwingWorker पर एक नज़र डालें।

+0

@ होवरक्राफ्टफुलऑफल्स मैंने आपके नोट के लिए उत्तर में सुधार किया है। – Behnil

+0

मैं होवरक्राफ्ट से सहमत हूं, मुझे लगता है कि 'स्विंगवर्कर' इस सरल समस्या के लिए मार डाला गया है – MadProgrammer

+0

आपकी मदद के लिए धन्यवाद – Ron

संबंधित मुद्दे