दिलचस्प पोस्ट
जो ऑपरेटर के बराबर है (== बनाम ===) का उपयोग जावास्क्रिप्ट तुलना में किया जाना चाहिए? एक स्काला प्रकार के सदस्यों को एक हैश के बजाय डॉट के बजाय क्यों चुनता है? Jquery के साथ एकाधिक divs दिखाएँ / छिपाएँ क्या UITableViewStylePlain के साथ UITableView में फ्लोटिंग हेडर अक्षम करना संभव है? मैं एमएसएसक्यूएल में कंपनी के नामों का फजी मैच कैसे कर सकता हूं, जो कि ऑटो-पूर्ण के लिए PHP है? स्तंभों में पाई चार्ट के लिए किंवदंती कैसे प्रदर्शित करें? खिड़कियों और मैक पर @ फ़ॉन्ट-चेहरे एंटी-अलियासिंग प्रोग्राम को एक लेआउट में बटन जोड़ें JQuery के प्रतिस्थापन () और html () के बीच अंतर क्या है? ऐप बंडलर के साथ मैक ओएसएक्स ऐप बंडल के लिए जार सभी variadic टेम्पलेट तर्क के लिए लक्षण की जाँच करें कमांड लाइन का उपयोग करके गनोम टर्मिनल में एक नया टैब खोलें पायथन की 'निजी' विधियां वास्तव में निजी क्यों नहीं हैं? संख्या को जोड़ने का प्रयास करते समय + का उपयोग नहीं कर सकते किसी iPhone ऐप पर SQLite डेटाबेस जोड़ें

जावा और जीयूआई – एक्शनलिस्टनर एमवीसी पैटर्न के अनुसार कहाँ हैं?

मैं वर्तमान में एक टेम्पलेट जावा अनुप्रयोग लिख रहा हूं और मुझे यकीन है कि अगर ActionListeners संबंधित हैं, तो मैं साफ तौर पर MVC पैटर्न का पालन करना चाहता हूं।

उदाहरण स्विंग आधारित है, लेकिन यह फ्रेमवर्क के बारे में नहीं है बल्कि जीयूआई बनाने के लिए किसी भी रूपरेखा का उपयोग करते हुए जावा में एमवीसी की बुनियादी अवधारणा है।

मैंने एक बिल्कुल सरल आवेदन के साथ शुरू किया जिसमें एक जेफ्रेम और एक जेबटन (फ्रेम का निपटान करने के लिए इसलिए आवेदन को बंद करें)। इस पोस्ट का अनुपालन कोड। कुछ भी वाकई खास नहीं, सिर्फ यह स्पष्ट करने के लिए कि हम किस बारे में बात कर रहे हैं। मैंने अभी तक मॉडल के साथ शुरू नहीं किया था क्योंकि यह प्रश्न मुझे बहुत ज्यादा गुस्सा दिलाना था

पहले से ही एक समान प्रश्न (ओं) से अधिक हो चुके हैं, जैसे:
कई ActionListeners के साथ MVC पैटर्न
जावा स्विंग – जहां ActionListener जाना चाहिए?

लेकिन उनमें से कोई वास्तव में संतुष्ट नहीं था क्योंकि मैं दो चीजों को जानना चाहता हूं:

  • क्या यह एक अलग पैकेज में सभी ActionListeners है उचित है?
    • मैं दृश्य और नियंत्रक, विशेषताओं की पठनीयता के लिए ऐसा करना चाहता हूं अगर वहाँ बहुत सारे श्रोताओं है
  • अगर मैं कंट्रोलर के अंदर एक उप वर्ग नहीं है, तो मैं ActionListener के भीतर से एक कंट्रोलर फ़ंक्शन कैसे निष्पादित करूं? (अनुवर्ती सवाल)

मुझे उम्मीद है कि यह बहुत सामान्य या अस्पष्ट नहीं है, मैं यहां पूछ रहा हूं, लेकिन यह मुझे थोड़ी देर के लिए सोचता है। मैंने हमेशा अपने तरीके से इस्तेमाल किया , ActionHandler को नियंत्रक के बारे में बताया , लेकिन यह सही नहीं लगता है, इसलिए मैं अंततः यह जानना चाहता हूं कि यह ठीक से कैसे किया जाता है।

सधन्यवाद,
जेसन


नियंत्रक:

package controller; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import view.MainView; public class MainController { MainView mainView = new MainView(); public MainController() { this.initViewActionListeners(); } private void initViewActionListeners() { mainView.initButtons(new CloseListener()); } public class CloseListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { mainView.dispose(); } } } 

राय:

 package view; import java.awt.Dimension; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class MainView extends JFrame { JButton button_close = new JButton(); JPanel panel_mainPanel = new JPanel(); private static final long serialVersionUID = 5791734712409634055L; public MainView() { setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setSize(500, 500); this.add(panel_mainPanel); setVisible(true); } public void initButtons(ActionListener actionListener) { this.button_close = new JButton("Close"); this.button_close.setSize(new Dimension(100, 20)); this.button_close.addActionListener(actionListener); this.panel_mainPanel.add(button_close); } } 

वेब के समाधान से एकत्रित समाधान "जावा और जीयूआई – एक्शनलिस्टनर एमवीसी पैटर्न के अनुसार कहाँ हैं?"

स्विंग के साथ जवाब देने के लिए यह एक बहुत ही कठिन प्रश्न है, क्योंकि स्विंग शुद्ध एमवीसी क्रियान्वयन नहीं है, दृश्य और नियंत्रक मिश्रित होते हैं।

तकनीकी रूप से, एक मॉडल और नियंत्रक को बातचीत करने में सक्षम होना चाहिए और नियंत्रक और दृष्टिकोण को बातचीत करने में सक्षम होना चाहिए, लेकिन दृश्य और मॉडल को कभी भी बातचीत नहीं करना चाहिए, जो स्पष्ट रूप से स्विंग काम नहीं करता है, लेकिन यह एक और बहस है …

एक और मुद्दा यह है कि आप वास्तव में यूआई घटकों को किसी के सामने खड़ा नहीं करना चाहते हैं, नियंत्रक को ध्यान नहीं देना चाहिए कि कैसे कुछ निश्चित क्रियाएं होती हैं, केवल वे कर सकते हैं।

यह सुझाव दे सकता है कि आपके यूआई नियंत्रणों से जुड़ी ActionListener को देखने के द्वारा बनाए रखा जाना चाहिए। इस दृश्य को तब नियंत्रक को सतर्क कर देना चाहिए कि किसी प्रकार की कार्रवाई हुई है। इसके लिए, आप एक और ActionListener उपयोग कर सकते हैं, दृश्य द्वारा प्रबंधित किया गया है, जिस पर नियंत्रक का सदस्यता लिया गया है।

बेहतर अभी तक, मैं एक समर्पित दृष्टिकोण श्रोता होगा, जो कि इस दृश्य को उत्पन्न करने वाली क्रियाओं का वर्णन करता है, उदाहरण के लिए …

 public interface MainViewListener { public void didPerformClose(MainView mainView); } 

नियंत्रक तब इस श्रोता के माध्यम से देखने के लिए सदस्यता लेंगे और दृश्य को कॉल किया didPerformClose (जब इस मामले में) बंद बटन दबाया जाता है।

यहां तक ​​कि इस उदाहरण में, मैं एक "मुख्य दृश्य" इंटरफ़ेस बनाने की कोशिश करूँगा, जिसमें गुण (सेटर्स और गेस्टर्स) और कार्यों (श्रोताओं / कॉलबैक) का वर्णन किया गया है कि कोई भी कार्यान्वयन प्रदान करने की गारंटी है, तो आपको इसकी परवाह नहीं है कि ये कैसे कार्रवाई होती है, केवल जब वे करते हैं, तो आपको कुछ करने की उम्मीद है …

प्रत्येक स्तर पर आप खुद से पूछना चाहते हैं, किसी अन्य तत्व के लिए किसी भी तत्व (मॉडल या नियंत्रक या दृश्य को बदलना) कितना आसान होगा? यदि आप अपने आप को कोड decouple करने के लिए मिल जाए, तो आप एक समस्या है। इंटरफ़ेस के माध्यम से संचार करें और परतों के बीच युग्मन की मात्रा का प्रयास करें और कम करें और प्रत्येक परत को दूसरों के बारे में पता है कि वे केवल ठेके बनाए रखते हैं

अपडेट किया गया …

एक उदाहरण के लिए इसे लेते हैं …

लॉग इन करें

वास्तव में दो विचार हैं (वास्तविक संवाद छूटने के लिए), क्रेडेंशियल्स दृश्य और लॉगिन दृश्य हैं, हां, वे अलग-अलग हैं जैसे आप देखेंगे।

CredentialsView

क्रेडेंशियल्स दृश्य प्रमाणीकृत होने वाले विवरणों को एकत्र करने के लिए जिम्मेदार है, उपयोगकर्ता नाम और पासवर्ड। यह कंट्रोलर को यह जानकारी देने के लिए बताएगा कि ये क्रेडेंशियल्स कब बदल दिए गए हैं, क्योंकि नियंत्रक "लॉगिन" बटन को सक्षम करने जैसे कुछ कार्रवाई कर सकता है …

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

 public interface CredentialsView { public String getUserName(); public char[] getPassword(); public void willAuthenticate(); public void authenticationFailed(); public void authenticationSucceeded(); public void setCredentialsViewController(CredentialsViewController listener); } public interface CredentialsViewController { public void credientialsDidChange(CredentialsView view); } 

CredentialsPane

CredentialsPane एक CredentialsPane का भौतिक कार्यान्वयन है, यह अनुबंध लागू करता है, लेकिन इसे अपनी आंतरिक स्थिति का प्रबंधन करता है अनुबंध कैसे प्रबंधित किया जाता है नियंत्रक के लिए अपरिवर्तनीय है, यह केवल अनुबंध को बरकरार रखने की परवाह करता है …

 public class CredentialsPane extends JPanel implements CredentialsView { private CredentialsViewController controller; private JTextField userNameField; private JPasswordField passwordField; public CredentialsPane(CredentialsViewController controller) { setCredentialsViewController(controller); setLayout(new GridBagLayout()); userNameField = new JTextField(20); passwordField = new JPasswordField(20); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(2, 2, 2, 2); gbc.anchor = GridBagConstraints.EAST; add(new JLabel("Username: "), gbc); gbc.gridy++; add(new JLabel("Password: "), gbc); gbc.gridx = 1; gbc.gridy = 0; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; add(userNameField, gbc); gbc.gridy++; add(passwordField, gbc); DocumentListener listener = new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { getCredentialsViewController().credientialsDidChange(CredentialsPane.this); } @Override public void removeUpdate(DocumentEvent e) { getCredentialsViewController().credientialsDidChange(CredentialsPane.this); } @Override public void changedUpdate(DocumentEvent e) { getCredentialsViewController().credientialsDidChange(CredentialsPane.this); } }; userNameField.getDocument().addDocumentListener(listener); passwordField.getDocument().addDocumentListener(listener); } @Override public CredentialsViewController getCredentialsViewController() { return controller; } @Override public String getUserName() { return userNameField.getText(); } @Override public char[] getPassword() { return passwordField.getPassword(); } @Override public void willAuthenticate() { userNameField.setEnabled(false); passwordField.setEnabled(false); } @Override public void authenticationFailed() { userNameField.setEnabled(true); passwordField.setEnabled(true); userNameField.requestFocusInWindow(); userNameField.selectAll(); JOptionPane.showMessageDialog(this, "Authentication has failed", "Error", JOptionPane.ERROR_MESSAGE); } @Override public void authenticationSucceeded() { // Really don't care, but you might want to stop animation, for example... } public void setCredentialsViewController(CredentialsViewController controller){ this.controller = controller; } } 

LoginView

LoginView एक CredentialsView LoginView प्रबंधित करने के लिए जिम्मेदार है, लेकिन जब भी प्रमाणीकरण होना चाहिए या यदि प्रयोक्ता द्वारा प्रक्रिया रद्द कर दी गई हो तो LoginViewController इन LoginViewController को सूचित करने के लिए, कुछ माध्यमों के माध्यम से …

समान रूप से, LoginViewController इन LoginViewController देखेंगे कि प्रमाणीकरण कब होने वाला है और अगर प्रमाणीकरण विफल रहा है या सफल हुआ है

 public interface LoginView { public CredentialsView getCredentialsView(); public void willAuthenticate(); public void authenticationFailed(); public void authenticationSucceeded(); public void dismissView(); public LoginViewController getLoginViewController(); } public interface LoginViewController { public void authenticationWasRequested(LoginView view); public void loginWasCancelled(LoginView view); } 

LoginPane

LoginPane विशेष प्रकार का है, यह LoginViewController इन LoginViewController नियंत्रक के दृश्य के रूप में काम कर LoginViewController , लेकिन यह CredentialsView दृश्य के नियंत्रक के रूप में भी काम कर रहा है। यह महत्वपूर्ण है, क्योंकि ऐसा कुछ नहीं कह रहा है कि कोई दृश्य नियंत्रक नहीं हो सकता, लेकिन मैं इस बात के बारे में सावधान रहना चाहूंगा कि आप इस तरह से कैसे काम करते हैं, क्योंकि यह हमेशा ऐसा करने के लिए समझ में नहीं आता है, लेकिन क्योंकि दो विचार जानकारी इकट्ठा करने और घटनाओं का प्रबंधन करने के लिए मिलकर काम करना, इस मामले में यह समझ में आया।

चूंकि LoginPane को LoginPane में बदलाव के आधार पर अपनी खुद की स्थिति LoginPane होगी, इसलिए LoginPane को इस मामले में नियंत्रक के रूप में कार्य करने की इजाजत देता है, अन्यथा आपको अधिक विधियों की आपूर्ति करने की आवश्यकता होगी जो कि उस राज्य को नियंत्रित करते हैं बटन, लेकिन यह नियंत्रक को UI तर्क को खून बह रहा है …

 public static class LoginPane extends JPanel implements LoginView, CredentialsViewController { private LoginViewController controller; private CredentialsPane credientialsView; private JButton btnAuthenticate; private JButton btnCancel; private boolean wasAuthenticated; public LoginPane(LoginViewController controller) { setLoginViewController(controller); setLayout(new BorderLayout()); setBorder(new EmptyBorder(8, 8, 8, 8)); btnAuthenticate = new JButton("Login"); btnCancel = new JButton("Cancel"); JPanel buttons = new JPanel(); buttons.add(btnAuthenticate); buttons.add(btnCancel); add(buttons, BorderLayout.SOUTH); credientialsView = new CredentialsPane(this); add(credientialsView); btnAuthenticate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getLoginViewController().authenticationWasRequested(LoginPane.this); } }); btnCancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getLoginViewController().loginWasCancelled(LoginPane.this); // I did think about calling dispose here, // but's not really the the job of the cancel button to decide what should happen here... } }); validateCreientials(); } public static boolean showLoginDialog(LoginViewController controller) { final LoginPane pane = new LoginPane(controller); JDialog dialog = new JDialog(); dialog.setTitle("Login"); dialog.setModal(true); dialog.add(pane); dialog.pack(); dialog.setLocationRelativeTo(null); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { pane.getLoginViewController().loginWasCancelled(pane); } }); dialog.setVisible(true); return pane.wasAuthenticated(); } public boolean wasAuthenticated() { return wasAuthenticated; } public void validateCreientials() { CredentialsView view = getCredentialsView(); String userName = view.getUserName(); char[] password = view.getPassword(); if ((userName != null && userName.trim().length() > 0) && (password != null && password.length > 0)) { btnAuthenticate.setEnabled(true); } else { btnAuthenticate.setEnabled(false); } } @Override public void dismissView() { SwingUtilities.windowForComponent(this).dispose(); } @Override public CredentialsView getCredentialsView() { return credientialsView; } @Override public void willAuthenticate() { getCredentialsView().willAuthenticate(); btnAuthenticate.setEnabled(false); } @Override public void authenticationFailed() { getCredentialsView().authenticationFailed(); validateCreientials(); wasAuthenticated = false; } @Override public void authenticationSucceeded() { getCredentialsView().authenticationSucceeded(); validateCreientials(); wasAuthenticated = true; } public LoginViewController getLoginViewController() { return controller; } public void setLoginViewController(LoginViewController controller) { this.controller = controller; } @Override public void credientialsDidChange(CredentialsView view) { validateCreientials(); } } 

कार्यरत उदाहरण

 import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import sun.net.www.protocol.http.HttpURLConnection; public class Test { protected static final Random AUTHENTICATION_ORACLE = new Random(); public static void main(String[] args) { new Test(); } public interface CredentialsView { public String getUserName(); public char[] getPassword(); public void willAuthenticate(); public void authenticationFailed(); public void authenticationSucceeded(); public CredentialsViewController getCredentialsViewController(); } public interface CredentialsViewController { public void credientialsDidChange(CredentialsView view); } public interface LoginView { public CredentialsView getCredentialsView(); public void willAuthenticate(); public void authenticationFailed(); public void authenticationSucceeded(); public void dismissView(); public LoginViewController getLoginViewController(); } public interface LoginViewController { public void authenticationWasRequested(LoginView view); public void loginWasCancelled(LoginView view); } public Test() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } LoginViewController controller = new LoginViewController() { @Override public void authenticationWasRequested(LoginView view) { view.willAuthenticate(); LoginAuthenticator authenticator = new LoginAuthenticator(view); authenticator.authenticate(); } @Override public void loginWasCancelled(LoginView view) { view.dismissView(); } }; if (LoginPane.showLoginDialog(controller)) { System.out.println("You shell pass"); } else { System.out.println("You shell not pass"); } System.exit(0); } }); } public class LoginAuthenticator { private LoginView view; public LoginAuthenticator(LoginView view) { this.view = view; } public void authenticate() { Thread t = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException ex) { Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (AUTHENTICATION_ORACLE.nextBoolean()) { view.authenticationSucceeded(); view.dismissView(); } else { view.authenticationFailed(); } } }); } }); t.start(); } } public static class LoginPane extends JPanel implements LoginView, CredentialsViewController { private LoginViewController controller; private CredentialsPane credientialsView; private JButton btnAuthenticate; private JButton btnCancel; private boolean wasAuthenticated; public LoginPane(LoginViewController controller) { setLoginViewController(controller); setLayout(new BorderLayout()); setBorder(new EmptyBorder(8, 8, 8, 8)); btnAuthenticate = new JButton("Login"); btnCancel = new JButton("Cancel"); JPanel buttons = new JPanel(); buttons.add(btnAuthenticate); buttons.add(btnCancel); add(buttons, BorderLayout.SOUTH); credientialsView = new CredentialsPane(this); add(credientialsView); btnAuthenticate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getLoginViewController().authenticationWasRequested(LoginPane.this); } }); btnCancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getLoginViewController().loginWasCancelled(LoginPane.this); // I did think about calling dispose here, // but's not really the the job of the cancel button to decide what should happen here... } }); validateCreientials(); } public static boolean showLoginDialog(LoginViewController controller) { final LoginPane pane = new LoginPane(controller); JDialog dialog = new JDialog(); dialog.setTitle("Login"); dialog.setModal(true); dialog.add(pane); dialog.pack(); dialog.setLocationRelativeTo(null); dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { pane.getLoginViewController().loginWasCancelled(pane); } }); dialog.setVisible(true); return pane.wasAuthenticated(); } public boolean wasAuthenticated() { return wasAuthenticated; } public void validateCreientials() { CredentialsView view = getCredentialsView(); String userName = view.getUserName(); char[] password = view.getPassword(); if ((userName != null && userName.trim().length() > 0) && (password != null && password.length > 0)) { btnAuthenticate.setEnabled(true); } else { btnAuthenticate.setEnabled(false); } } @Override public void dismissView() { SwingUtilities.windowForComponent(this).dispose(); } @Override public CredentialsView getCredentialsView() { return credientialsView; } @Override public void willAuthenticate() { getCredentialsView().willAuthenticate(); btnAuthenticate.setEnabled(false); } @Override public void authenticationFailed() { getCredentialsView().authenticationFailed(); validateCreientials(); wasAuthenticated = false; } @Override public void authenticationSucceeded() { getCredentialsView().authenticationSucceeded(); validateCreientials(); wasAuthenticated = true; } public LoginViewController getLoginViewController() { return controller; } public void setLoginViewController(LoginViewController controller) { this.controller = controller; } @Override public void credientialsDidChange(CredentialsView view) { validateCreientials(); } } public static class CredentialsPane extends JPanel implements CredentialsView { private CredentialsViewController controller; private JTextField userNameField; private JPasswordField passwordField; public CredentialsPane(CredentialsViewController controller) { setCredentialsViewController(controller); setLayout(new GridBagLayout()); userNameField = new JTextField(20); passwordField = new JPasswordField(20); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(2, 2, 2, 2); gbc.anchor = GridBagConstraints.EAST; add(new JLabel("Username: "), gbc); gbc.gridy++; add(new JLabel("Password: "), gbc); gbc.gridx = 1; gbc.gridy = 0; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; add(userNameField, gbc); gbc.gridy++; add(passwordField, gbc); DocumentListener listener = new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { getCredentialsViewController().credientialsDidChange(CredentialsPane.this); } @Override public void removeUpdate(DocumentEvent e) { getCredentialsViewController().credientialsDidChange(CredentialsPane.this); } @Override public void changedUpdate(DocumentEvent e) { getCredentialsViewController().credientialsDidChange(CredentialsPane.this); } }; userNameField.getDocument().addDocumentListener(listener); passwordField.getDocument().addDocumentListener(listener); } @Override public CredentialsViewController getCredentialsViewController() { return controller; } @Override public String getUserName() { return userNameField.getText(); } @Override public char[] getPassword() { return passwordField.getPassword(); } @Override public void willAuthenticate() { userNameField.setEnabled(false); passwordField.setEnabled(false); } @Override public void authenticationFailed() { userNameField.setEnabled(true); passwordField.setEnabled(true); userNameField.requestFocusInWindow(); userNameField.selectAll(); JOptionPane.showMessageDialog(this, "Authentication has failed", "Error", JOptionPane.ERROR_MESSAGE); } @Override public void authenticationSucceeded() { // Really don't care, but you might want to stop animation, for example... } public void setCredentialsViewController(CredentialsViewController controller) { this.controller = controller; } } } 

वे नियंत्रण से जुड़े हुए हैं, लेकिन उन्हें नियंत्रण का एक सीधा भाग नहीं होना पड़ता है। उदाहरण के लिए, कृपया नीचे पोस्ट किए गए कोड को देखें जो कि मैं एक और प्रश्न के लिए तैयारी कर रहा हूं, एक अनाम आंतरिक कक्षाएं और युग्मन पर, यहां मैं अपने सभी बटनों को अनाम आंतरिक कार्रवाइयां (जो कि ActionListeners, निश्चित रूप से) देता है, और फिर क्रियाओं को बदलने के लिए GUI राज्य जीयूआई (नियंत्रण) के लिए कोई भी श्रोताओं को इस बदलाव की सूचना दी जाएगी, और तब उसके अनुसार कार्य कर सकते हैं।

 import java.awt.*; import java.awt.event.*; java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.*; import javax.swing.event.SwingPropertyChangeSupport; public class AnonymousInnerEg2 { private static void createAndShowUI() { GuiModel2 model = new GuiModel2(); GuiPanel2 guiPanel = new GuiPanel2(); GuiControl2 guiControl = new GuiControl2(); guiControl.setGuiPanel(guiPanel); guiControl.setGuiModel(model); try { guiControl.init(); } catch (GuiException2 e) { e.printStackTrace(); System.exit(-1); } JFrame frame = new JFrame("AnonymousInnerEg"); frame.getContentPane().add(guiPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } enum GuiState { BASE("Base"), START("Start"), END("End"); private String name; private GuiState(String name) { this.name = name; } public String getName() { return name; } } class GuiModel2 { public static final String STATE = "state"; private SwingPropertyChangeSupport support = new SwingPropertyChangeSupport(this); private GuiState state = GuiState.BASE; public GuiState getState() { return state; } public void setState(GuiState state) { GuiState oldValue = this.state; GuiState newValue = state; this.state = state; support.firePropertyChange(STATE, oldValue, newValue); } public void addPropertyChangeListener(PropertyChangeListener l) { support.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { support.removePropertyChangeListener(l); } } @SuppressWarnings("serial") class GuiPanel2 extends JPanel { public static final String STATE = "state"; private String state = GuiState.BASE.getName(); private JLabel stateField = new JLabel("", SwingConstants.CENTER); public GuiPanel2() { JPanel btnPanel = new JPanel(new GridLayout(1, 0, 5, 0)); for (final GuiState guiState : GuiState.values()) { btnPanel.add(new JButton(new AbstractAction(guiState.getName()) { { int mnemonic = (int) getValue(NAME).toString().charAt(0); putValue(MNEMONIC_KEY, mnemonic); } @Override public void actionPerformed(ActionEvent e) { String name = getValue(NAME).toString(); setState(name); } })); } setLayout(new BorderLayout()); add(stateField, BorderLayout.PAGE_START); add(btnPanel, BorderLayout.CENTER); } public String getState() { return state; } public void setState(String state) { String oldValue = this.state; String newValue = state; this.state = state; firePropertyChange(STATE, oldValue, newValue); } public void setStateField(String name) { stateField.setText(name); } } class GuiControl2 { private GuiPanel2 guiPanel; private GuiModel2 model; private boolean allOK = false; public void setGuiPanel(GuiPanel2 guiPanel) { this.guiPanel = guiPanel; guiPanel.addPropertyChangeListener(GuiPanel2.STATE, new GuiPanelStateListener()); } public void init() throws GuiException2 { if (model == null) { throw new GuiException2("Model is null"); } if (guiPanel == null) { throw new GuiException2("GuiPanel is null"); } allOK = true; guiPanel.setStateField(model.getState().getName()); } public void setGuiModel(GuiModel2 model) { this.model = model; model.addPropertyChangeListener(new ModelListener()); } private class GuiPanelStateListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { if (!allOK) { return; } if (GuiPanel2.STATE.equals(evt.getPropertyName())) { String text = guiPanel.getState(); model.setState(GuiState.valueOf(text.toUpperCase())); } } } private class ModelListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { if (!allOK) { return; } if (GuiModel2.STATE.equals(evt.getPropertyName())) { GuiState state = (GuiState) evt.getNewValue(); guiPanel.setStateField(state.getName()); } } } } @SuppressWarnings("serial") class GuiException2 extends Exception { public GuiException2() { super(); } public GuiException2(String message) { super(message); } } 

हालांकि चेतावनी में नोट: मैं एक पेशेवर सांकेतिक शब्दों में बदलनेवाला या यहां तक ​​कि एक विश्वविद्यालय प्रशिक्षित सांकेतिक शब्दों में बदलनेवाला नहीं हूँ, इसलिए कृपया इसे केवल मेरी राय के रूप में ही ले लो।

मैं वर्तमान में स्कूल में जावा सीख रहा हूं। शिक्षकों ने हमें बताया, कि श्रोताओं को हमेशा नियंत्रक वर्ग के अंदर घोषित करना होगा। जिस तरह से मैं करता हूं, वह एक विधि को लागू करना है जैसे श्रोताओं () अंदर सभी श्रोता हैं- अनाम कक्षाओं का उपयोग करते हुए घोषणाएं। यही तरीका मेरे शिक्षकों को देखना है, लेकिन स्पष्ट रूप से, मुझे वाकई यकीन नहीं है कि उन्हें ये सब सही मिले।