当前位置: 首页 > 知识库问答 >
问题:

从依赖于类B的类A中打破一个time(true)依赖

黄博艺
2023-03-14

考虑下面这个只获得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]);

    }
}

现在<code>服务器控制器<code>处于一个while(true)循环中,直到用户输入IP和端口。

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

共有1个答案

司空祯
2023-03-14

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

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

正如我们在前面的问题中所讨论的,一个Swing解决方案是:使用模态对话框获取信息。对话框的模式将暂停调用代码中的程序流,直到对话框被处理。

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

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

  • 从JFrame修改独立的JPanels
  • Java不断添加按钮!-JFrames

编辑<br>例如,用<code>/!!标记的更改 注释:

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;
   }
}
 类似资料:
  • 我已经定义了一个枚举类型,详细描述了用于给灰度图像着色的各种调色板,为此我使用了描述属性和TypeConver,以便使用我绑定到该类型的组合框、列表框等枚举值的描述字符串。枚举看起来像这样: EnumDescriptionTypeConverter如下所示: 使用它,我可以绑定enum类型,比如组合框的ItemsSource属性,并让描述字符串自动用作组合框元素,使用另一个自定义标记扩展类,我认为

  • Dependencies serve many different purposes. Some dependencies are needed to build your project, others are needed when you’re running your program. As such there are a number of different types of dep

  • 例如,我有依赖性:

  • 问题内容: 我有一个项目,该项目依赖于由供应商控制的工件。该工件包含一些我依赖的类,其中一些类较旧并且会引起问题。有没有办法让Maven自动扩展jar,删除类并将它们重新打包为依赖项?我会举一个例子。 所以- 我需要使用在项目网站,但我需要使用从神器。我无法修改Supplier:artifact或us:dependency。 有任何想法吗?! 问题答案: 从版本2.0.9开始,maven保留了类路

  • 对于一个类,我有两个路径名相同的依赖项。 比如: 当我安装这两个依赖项时,我以错误结束。(如果我只使用1个依赖项,则工作正常) 我需要这两个,因为我需要第二依赖项中的其他包。 在我的maven pom文件中。 有没有一种方法可以要求排除导致问题的类? 我知道我可以排除这里的另一个依赖项。但是我可以只排除这个导致问题的类吗? 或者至少排除包com. a. b. c. d. e. f? 考虑到两个依赖

  • 问题内容: 我已经搜索了很多,但是我发现的主要是python中的递归编程示例。因此,问题来了: 我该如何实现? 问题答案: 一切在Python中都是动态的-甚至是类声明。在初始声明之后,没有什么可以阻止您修改类的内容的: 注意:如果您不太熟悉Python,则该关键字仅允许您说“这里什么都没有”-除非A类的空值与本例中的一样空,否则它并不重要!