2012-09-13 19 views
5

मेरे पास एक ही पैकेज में दो कक्षाएं हैं। मैंने एक वर्ग में static variable घोषित कर दिया है और उस चर को किसी अन्य श्रेणी में एक्सेस करना चाहते हैं।किसी अन्य वर्ग से स्थिर स्थिर चर

यहाँ मेरी कोड है, जिसमें मैं स्थिर चर

public class wampusGUI extends javax.swing.JFrame { 

    static String userCommand; 

    public wampusGUI() { 
     initComponents(); 
    } 

    public void setTextArea(String text) { 
     displayTextArea.append(text); 
    } 

    private void enterButtonActionPerformed(java.awt.event.ActionEvent evt) { 
     userCommand = commandText.getText(); 
    } 

    public static void main(String args[]) { 
     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       wampusGUI w = new wampusGUI(); 
       w.setVisible(true); 
       Game g = new Game(w); 
       g.play(); 
      } 
     }); 
    } 
} 

यहाँ घोषणा की है कोड, जिसमें मैं चर का उपयोग करने के

public class Game { 

    private wampusGUI gui; 

    public Game(wampusGUI w) { 
     world = new World(); 
     world.start(); 
     gui = w; 
    } 

    public void play() { 
     gui.setTextArea(welcome()); 
     gui.setTextArea(describe()); 
     for (;;) { 
      String s = userCommand; // here value should come should 
      System.out.println(userCommand); 
      Command c = Command.create(s); 
      String r = c.perform(world); 
      // is game over? 
      if (r == null) { 
       break; 
      } 
      System.out.println(r); 
     } 
     System.out.println("Game over"); 
    } 
} 

हालांकि चाहते है, मैं पहले से चर पारित कर सकते हैं एक तर्क के रूप में वर्ग। लेकिन समस्या यह है कि, जब मैं प्रोग्राम चलाऊंगा तो मूल्य पहली बार शून्य हो रहा है, जिसे मैं नहीं चाहता हूं। मैं चाहता हूं कि जब मैं textfield में मान दर्ज करता हूं तो इसे किसी अन्य वर्ग में जाना चाहिए।

धन्यवाद।

+7

"मूल्य पहली बार शून्य हो रहा है" का क्या मतलब है? असल में आपको अपना डिज़ाइन बदलना चाहिए - एक वैश्विक चर होना वास्तव में * अच्छा * नहीं है। –

+1

मैं @jon से सहमत हूं। जब तक उपयोगकर्ता को इसे बदलने का मौका नहीं मिलता तब तक आपकी स्ट्रिंग का सभ्य मूल्य नहीं होगा। लूप के लिए भी हमेशा के लिए एक स्विंग आवेदन के लिए एक अच्छा डिजाइन नहीं है। मैं सोच रहा हूं कि क्या आप वास्तव में उपयोगकर्ता के जेटीक्स्टफिल्ड के राज्य को बदलने और फिर इस पर अभिनय करने के लिए सुनने के लिए श्रोता का उपयोग करना चाहते हैं। शायद आप एक स्विंग टाइमर का उपयोग करना भी चाहेंगे, हालांकि यह जानना मुश्किल है कि जब तक हम आपके कार्यक्रम के बारे में अधिक नहीं जानते हैं और यह क्या करना है। –

+0

कृपया हमें बताएं: आप इस कोड के साथ क्या करने की कोशिश कर रहे हैं? –

उत्तर

2

मेरा सुझाव है कि आप एक तरह से या किसी अन्य के एक श्रोता का उपयोग खेल वस्तु के लिए सुनने और जीयूआई वस्तु की स्थिति में परिवर्तन करने के लिए प्रतिक्रिया करने के लिए अनुमति देने के लिए। ऐसा करने के कई तरीके हैं, लेकिन मैंने पाया है कि सबसे सुरुचिपूर्ण और उपयोगी में से एक है स्विंग के अपने सहज संपत्ति चेंजपोर्ट का उपयोग करना ताकि आप PropertyChangeListeners का उपयोग कर सकें। सभी स्विंग घटक आपको इसके लिए एक PropertyChangeListener जोड़ने की अनुमति देंगे।और इसलिए मैं सुझाव है कि आप ऐसा करते हैं, आप खेल इतना की तरह अपने WampusGUI वर्ग के लिए एक जोड़ने (जो बड़े अक्षरों में लिखा होना चाहिए) वस्तु है कि:

public Game(WampusGUI w) { 
    gui = w; 

    gui.addPropertyChangeListener(new PropertyChangeListener() { 
    // .... 
    } 

इस खेल जीयूआई के राज्य के बदलावों को सुनने के लिए अनुमति देगा।

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

private void enterButtonActionPerformed(java.awt.event.ActionEvent evt) { 
    setUserCommand(commandText.getText()); 
} 

खेल की संपत्ति परिवर्तन श्रोता तो तरह जवाब देगा:

gui.addPropertyChangeListener(new PropertyChangeListener() { 

    @Override 
    public void propertyChange(PropertyChangeEvent pcEvt) { 

     // is the property being changed the one we're interested in? 
     if (WampusGUI.USER_COMMAND.equals(pcEvt.getPropertyName())) { 

      // get user command: 
      String userCommand = pcEvt.getNewValue().toString(); 

      // then we can do with it what we want 
      play(userCommand); 

     } 

    } 
    }); 

public class WampusGUI extends JFrame { 
    public static final String USER_COMMAND = "user command"; 
    // .... 

    private void setUserCommand(String userCommand) { 
     String oldValue = this.userCommand; 
     String newValue = userCommand; 
     this.userCommand = userCommand; 
     firePropertyChange(USER_COMMAND, oldValue, newValue); 
    } 

तो फिर तुम केवल इस सेटर प्रणाली द्वारा इस स्ट्रिंग के मूल्य बदल जाएगा

इस तकनीक की सुंदरियों में से एक यह है कि मनाई गई कक्षा, जीयूआई को पर्यवेक्षक वर्ग (गेम) के बारे में कोई जानकारी नहीं है। इसका एक छोटा सा उदाहरण उदाहरण इस प्रकार है:

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.*; 

public class WampusGUI extends JFrame { 
    public static final String USER_COMMAND = "user command"; 
    private String userCommand; 
    private JTextArea displayTextArea = new JTextArea(10, 30); 
    private JTextField commandText = new JTextField(10); 

    public WampusGUI() { 
     initComponents(); 
    } 

    private void setUserCommand(String userCommand) { 
     String oldValue = this.userCommand; 
     String newValue = userCommand; 
     this.userCommand = userCommand; 
     firePropertyChange(USER_COMMAND, oldValue, newValue); 
    } 

    private void initComponents() { 
     displayTextArea.setEditable(false); 
     displayTextArea.setFocusable(false); 
     JButton enterButton = new JButton("Enter Command"); 
     enterButton.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent evt) { 
      enterButtonActionPerformed(evt); 
     } 
     }); 
     JPanel commandPanel = new JPanel(); 
     commandPanel.add(commandText); 
     commandPanel.add(Box.createHorizontalStrut(15)); 
     commandPanel.add(enterButton); 

     JPanel mainPanel = new JPanel(); 
     mainPanel.setLayout(new BorderLayout()); 
     mainPanel.add(new JScrollPane(displayTextArea)); 
     mainPanel.add(commandPanel, BorderLayout.SOUTH); 
     add(mainPanel); 
    } 

    public void setTextArea(String text) { 
     displayTextArea.append(text); 
    } 

    private void enterButtonActionPerformed(java.awt.event.ActionEvent evt) { 
     setUserCommand(commandText.getText()); 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      WampusGUI w = new WampusGUI(); 
      w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      w.pack(); 
      w.setLocationRelativeTo(null); 
      w.setVisible(true); 
      Game g = new Game(w); 
      g.play(); 
     } 
     }); 
    } 
} 

class Game { 
    private WampusGUI gui; 

    public Game(WampusGUI w) { 
     gui = w; 

     gui.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent pcEvt) { 

      // is the property being changed the one we're interested in? 
      if (WampusGUI.USER_COMMAND.equals(pcEvt.getPropertyName())) { 

       // get user command: 
       String userCommand = pcEvt.getNewValue().toString(); 

       // then we can do with it what we want 
       play(userCommand); 

      } 
     } 
     }); 
    } 

    public void play() { 
     gui.setTextArea("Welcome!\n"); 
     gui.setTextArea("Please enjoy the game!\n"); 
    } 

    public void play(String userCommand) { 
     // here we can do what we want with the String. For instance we can display it in the gui: 
     gui.setTextArea("User entered: " + userCommand + "\n"); 
    } 

} 
0

मैं जॉन स्कीट साथ सहमत हैं कि यह एक अच्छा समाधान नहीं है ...

लेकिन मामले में यू चाहते उर समस्या का एक गंदा समाधान तो यू यह कोशिश कर सकते हैं: अन्य में

public class wampusGUI extends javax.swing.JFrame 
{ 
    private static wampusGUI myInstance; 
    public wampusGUI() 
    { 
     myInstance = this; 
     initComponents(); 
    } 

    public static void getUserCommand() 
    { 
     if(myInstance!=null) 
     { 
      return myInstance.commandText.getText(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
    ...... 
    ...... 
} 

कक्षा का उपयोग:

public void play() 
{ 
    ..... 
    //String s = userCommand; // here value should come should 
    String s = wampusGUI.getUserCommand(); 
    ..... 
} 

इस तरह का कोड हमारी कुछ विरासत परियोजनाओं में है ... और मुझे इससे नफरत है।

+0

इसके लिए कोई आवश्यकता नहीं है, और बहुत अधिक सुरुचिपूर्ण समाधान हैं। –

+0

मैंने कभी नहीं बताया कि यह एक सुरुचिपूर्ण समाधान है;) –

+0

सच है। मुझे लगता है कि यह निर्भर करता है कि प्रोग्रामर एक श्रोता के माध्यम से डेटा धक्का देना चाहता है या मतदान के माध्यम से खींचा जाना चाहता है। यदि संभव हो, तो मैं श्रोता दृष्टिकोण पसंद करता हूं, लेकिन ऐसा करना हमेशा संभव नहीं होता है। –

4

अपने कोड को देखते हुए, ऐसा लगता है कि आप एक निश्चित पाठ

gui.setTextArea(welcome()); 
gui.setTextArea(describe()); 

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

  1. उन setTextArea कॉल आप जो उपयोग करना चाहते हैं वह नहीं हैं। उपयोगकर्ता कभी भी स्वागत संदेश नहीं देख पाएगा क्योंकि इसे तुरंत संदेश संदेश द्वारा प्रतिस्थापित किया जाएगा।
  2. सुनिश्चित करें कि आप इवेंट डिस्पैच थ्रेड (ईडीटी) को अवरुद्ध नहीं करते हैं या कुछ भी नहीं दिखाया जाएगा। मुझे नहीं पता कि आपकी Command कक्षा क्या करेगी, लेकिन मुझे Event Dispatch Thread पर एक अनंत लूप दिखाई देता है जो कभी भी अच्छी बात नहीं है। अधिक जानकारी के लिए Concurrency in Swing tutorial पर एक नजर डालें
  3. कि for पाश के लिए धन्यवाद, उपयोगकर्ता केवल नहीं सक्षम इनपुट के लिए किसी भी आदेश हो जाएगा के रूप में EDT अपने पाश से निपटने में व्यस्त है। आपको जो चाहिए वह एक अवरुद्ध कॉल है जो उपयोगकर्ता को इनपुट प्रदान करने की अनुमति देता है (ईडीटी को अवरुद्ध नहीं करता है, बल्कि केवल आपके कोड के निष्पादन को अवरुद्ध करता है)। JOptionPane कक्षा में स्थिर विधियां इस के लिए बिल्कुल उपयुक्त हैं (उदा। JOptionPane#showInputDialog)। इन विधियों में उपयोगकर्ता इनपुट को किसी भी स्थिर चर के बिना कॉलिंग कोड पर वापस लाने के लिए एक तंत्र भी है, जो आपकी समस्या हल करता है।
संबंधित मुद्दे