从依赖于B类的A类中断一段时间(真实)依赖

时间:2014-03-30 22:13:45

标签: java while-loop dependencies

考虑以下只获取IP和端口号的类:

package view;


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import javax.swing.*;
import javax.swing.border.EmptyBorder;


/**
 * Server side
 * @author X
 *
 */
class ServerConnector implements ActionListener
{

    private JFrame m_frame = null;
    private JTextField m_serverIP;
    private JTextField m_serverPort; // you can use also JPasswordField
    private JButton m_submitButton;

    // location of the jframe
    private final int m_centerX = 500;
    private final int m_centerY = 300;

    // dimensions of the jframe
    private final int m_sizeX = 1650;
    private final int m_sizeY = 150;

    private String m_ip;
    private String m_port;

    private boolean ready = false;

    /**
     * Ctor
     */
    ServerConnector()
    {
        m_frame = new JFrame("Sever Side Listener");
        m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        m_serverIP = new JTextField(20);
        m_serverPort = new JTextField(20);

        JPanel gui = new JPanel(new BorderLayout(3,3));
        gui.setBorder(new EmptyBorder(5,5,5,5));
        gui.setSize(m_sizeX , m_sizeY);
        m_frame.setContentPane(gui);

        JPanel labels = new JPanel(new GridLayout(0,1));
        JPanel controls = new JPanel(new GridLayout(0,1));
        gui.add(labels, BorderLayout.WEST);
        gui.add(controls, BorderLayout.CENTER);

        labels.add(new JLabel("Server IP: "));
        controls.add(m_serverIP);
        labels.add(new JLabel("Server Port: "));
        controls.add(m_serverPort);
        m_submitButton = new JButton("Start Listening");
        m_submitButton.addActionListener(this);

        gui.add(m_submitButton, BorderLayout.SOUTH);
        m_frame.setLocation(m_centerX , m_centerY);
        m_frame.setSize(m_sizeX , m_sizeY);
        m_frame.pack();
        m_frame.setVisible(true);
    }

    public static void main(String[] args) {
        new ServerConnector();
    }

    @Override
    public void actionPerformed(ActionEvent event) {

        Object object = event.getSource();
        if (object == this.m_submitButton)
        {
            // grab all values from the connection box 
            // if one of them is missing then display an alert message 

            String ip = this.m_serverIP.getText().trim();
            String port = this.m_serverPort.getText().trim();

            if (ip.length() == 0)
            {
                JOptionPane.showMessageDialog(null, "Please enter IP address !");
                return;
            }

            if (port.length() == 0)
            {
                JOptionPane.showMessageDialog(null, "Please enter Port number!");
                return;
            }

            int s_port = 0;

            try
            {
                // try parse the Port number 
                // throws exception when an incorrect IP address 
                // is entered , and caught in the catch block 
                s_port = Integer.parseInt(port);
            }

            catch(Exception exp)
            {
                JOptionPane.showMessageDialog(null, "Port number is incorrect!");
                return;
            }

            try
            {
                // try parse the IP address 
                // throws exception when an incorrect IP address 
                // is entered , and caught in the catch block 
                InetAddress.getByName(ip);
            }

            catch(Exception exp)
            {
                JOptionPane.showMessageDialog(null, "IP address is incorrect!");
                return;
            }

            m_frame.dispose();
            this.m_ip = ip;
            this.m_port = port;
            ready = true;
            // new ServerGUI(ip , s_port);
        }


    }


    public boolean isReady()
    {
        return this.ready;
    }

    /**
     * 
     * @return
     */
    public String[] getIPandPort()
    {
        String[] ipPort = new String[2];
        ipPort[0] = this.m_ip;
        ipPort[1] = this.m_port;
        return ipPort;
    }
}

这将是控制器类

public class ServerController {

    String m_ip;
    int m_port;

    public static void main(String args[])
    {
        ServerConnector sc = new ServerConnector();

        while (!sc.isReady())
        {
            // run 
        }

        // get IP and port
        String[] ipPort = sc.getIPandPort();

        System.out.println("IP is :" + ipPort[0] + " and port is :" + ipPort[1]);

    }
}

现在ServerController处于while(true)循环中,直到用户输入IP和端口。

如何避免这种依赖(避免while循环)?

1 个答案:

答案 0 :(得分:2)

首先,摆脱while (true)循环,因为它的唯一目的是弄乱你的代码。

一般的解决方案是从阻止程序流的代码中获取用户的信息。但是如果在不能阻止其事件线程的GUI中需要这样做,则会出现问题。

One Swing解决方案正如我们之前在your previous question中所讨论的那样:使用模态对话框来获取信息。对话框的模态将暂停调用代码中的程序流,直到处理完对话框。

如果你想避免使用模态对话框,那么另一个通用的事件驱动解决方案是使用观察者设计模式 - 让另一个对象 通知 当信息或状态发生变化时。使用PropertyChangeSupport和PropertyChangeListeners可以很容易地实现这一点,尽管还有其他方法,包括使用Swing库中提供的XxxxListeners。

例如监听器使用和带Swing的MVC:


修改
例如,标有// !!评论的更改:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.InetAddress;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.SwingPropertyChangeSupport;

public class ServerController {

   String m_ip;
   int m_port;
   private static String[] ipPort;

   public static void main(String args[]) {
      final ServerConnector sc = new ServerConnector();

      sc.addPropertyChangeListener(new PropertyChangeListener() {
         @Override
         public void propertyChange(PropertyChangeEvent evt) {
            if (ServerConnector.READY.equals(evt.getPropertyName())) {
               if (sc.isReady()) {
                  ipPort = sc.getIPandPort();
                  System.out.println("IP is :" + ipPort[0] + " and port is :" + ipPort[1]);
               }
            }
         }
      });
   }
}

class ServerConnector implements ActionListener {
   public static final String READY = "ready"; //!!

   private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this); //!!
   private boolean ready = false;
   private JFrame m_frame = null;
   private JTextField m_serverIP;
   private JTextField m_serverPort; // you can use also JPasswordField
   private JButton m_submitButton;

   // location of the jframe
   private final int m_centerX = 500;
   private final int m_centerY = 300;

   // dimensions of the jframe
   private final int m_sizeX = 1650;
   private final int m_sizeY = 150;

   private String m_ip;
   private String m_port;


   /**
    * Ctor
    */
   ServerConnector() {
      m_frame = new JFrame("Sever Side Listener");
      m_frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      m_serverIP = new JTextField(20);
      m_serverPort = new JTextField(20);

      JPanel gui = new JPanel(new BorderLayout(3, 3));
      gui.setBorder(new EmptyBorder(5, 5, 5, 5));
      gui.setSize(m_sizeX, m_sizeY);
      m_frame.setContentPane(gui);

      JPanel labels = new JPanel(new GridLayout(0, 1));
      JPanel controls = new JPanel(new GridLayout(0, 1));
      gui.add(labels, BorderLayout.WEST);
      gui.add(controls, BorderLayout.CENTER);

      labels.add(new JLabel("Server IP: "));
      controls.add(m_serverIP);
      labels.add(new JLabel("Server Port: "));
      controls.add(m_serverPort);
      m_submitButton = new JButton("Start Listening");
      m_submitButton.addActionListener(this);

      gui.add(m_submitButton, BorderLayout.SOUTH);
      m_frame.setLocation(m_centerX, m_centerY);
      m_frame.setSize(m_sizeX, m_sizeY);
      m_frame.pack();
      m_frame.setVisible(true);
   }

   public static void main(String[] args) {
      new ServerConnector();
   }

   @Override
   public void actionPerformed(ActionEvent event) {

      Object object = event.getSource();
      if (object == this.m_submitButton) {
         // grab all values from the connection box
         // if one of them is missing then display an alert message

         String ip = this.m_serverIP.getText().trim();
         String port = this.m_serverPort.getText().trim();

         if (ip.length() == 0) {
            JOptionPane.showMessageDialog(null, "Please enter IP address !");
            return;
         }

         if (port.length() == 0) {
            JOptionPane.showMessageDialog(null, "Please enter Port number!");
            return;
         }

         int s_port = 0;

         try {
            // try parse the Port number
            // throws exception when an incorrect IP address
            // is entered , and caught in the catch block
            s_port = Integer.parseInt(port);
         }

         catch (Exception exp) {
            JOptionPane.showMessageDialog(null, "Port number is incorrect!");
            return;
         }

         try {
            // try parse the IP address
            // throws exception when an incorrect IP address
            // is entered , and caught in the catch block
            InetAddress.getByName(ip);
         }

         catch (Exception exp) {
            JOptionPane.showMessageDialog(null, "IP address is incorrect!");
            return;
         }

         m_frame.dispose();
         this.m_ip = ip;
         this.m_port = port;
         setReady(true); //!!
         // !! ready = true;
         // new ServerGUI(ip , s_port);
      }

   }

   // !! added
   public void setReady(boolean ready) {
      boolean oldValue = this.ready;
      boolean newValue = ready;
      this.ready = ready;
      pcSupport.firePropertyChange(READY, oldValue, newValue);
   }

   //!! added
   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

   //!! added
   public void removePropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(listener);
   }

   public boolean isReady() {
      return this.ready;
   }

   /**
    * 
    * @return
    */
   public String[] getIPandPort() {
      String[] ipPort = new String[2];
      ipPort[0] = this.m_ip;
      ipPort[1] = this.m_port;
      return ipPort;
   }
}