java - 连接 GUI (Swing) 和业务逻辑

标签 java swing observer-pattern business-logic

免责声明:- 以下示例是我在现实中尝试做的事情的高度缩小版本。

概述:

应用程序名称:随机数生成器。

所需的应用程序流程: RandomNumberLogic 类每 10 秒生成一个随机数。生成的数字应显示在 RandomNumberPanel 上。

应用程序设计目标:使 GUI 和业务逻辑尽可能分开。 (我猜低耦合就是我要找的词)。

代码:

BasicRandomApplication.java

package SideActivities;

import javax.swing.SwingUtilities;

public class BasicRandomApplication
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
           public void run()
           {
                new MainFrame();
                RandomNumberLogic x = new RandomNumberLogic();
                x.generateNumbers();
            }
        });
    }
}

MainFrame.java

package SideActivities;

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;

public class MainFrame extends JFrame
{
    RandomNumberPanel randomNumberPanel;

    MainFrame()
    { 
        randomNumberPanel = new RandomNumberPanel();

        this.setLayout(new BorderLayout());

        this.add(randomNumberPanel, BorderLayout.CENTER);
        this.setSize(new Dimension(400, 500));
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setLocationRelativeTo(null);
    }
}

RandomNumberLogic.java

package SideActivities;

import java.util.Random;

public class RandomNumberLogic
{
    private ModelListener listener;

    public void generateNumbers()
    {
        long firstTime = System.currentTimeMillis();
        int refreshRate = 10 * 1000;
        long delta = 0;
        while (true)
        {
            long secondTime = System.currentTimeMillis();
            delta += (secondTime - firstTime) / refreshRate;
            if (delta >= 1)
            {
                Random random = new Random();
                ModelEvent e = new ModelEvent();
                e.setNumber(random.nextInt());
                listener.refreshData(e);
                delta--;
           }
       }
   }

   public void setListener(ModelListener listener)
   {
        this.listener = listener;
   }
}

RandomNumberPanel.java

package SideActivities;

import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class RandomNumberPanel extends JPanel implements ModelListener
{
    private JLabel number;

    RandomNumberPanel()
    {
        number = new JLabel();

        this.setLayout(new BorderLayout());

        this.add(number, BorderLayout.CENTER);
        this.setBorder(BorderFactory.createLineBorder(Color.RED, 3));
    }

    @Override
    public void refreshData(ModelEvent e)
    {
        number.setText(e.getNumber() + "");
    }

}

ModelEvent.java

package SideActivities;

public class ModelEvent
{
    private int number;

    public void setNumber(int number)
    {
        this.number = number;
    }

    public int getNumber()
    {
        return this.number;
    }
}

ModelListener.java

 package SideActivities;

 public interface ModelListener
 {
     public void refreshData(ModelEvent e);
 }

问题 1) 为什么我的 GUI 应用程序需要很长时间才能开始显示某些内容?

问题 2)为什么会出现以下异常?

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at SideActivities.RandomNumberLogic.generateNumbers(RandomNumberLogic.java:23)
    at SideActivities.BasicRandomApplication$1.run(BasicRandomApplication.java:15)
    at java.awt.event.InvocationEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

问题 2 的解决方案)setListener 方法从未被调用。

我做了以下更改,但 GUI 仍然需要很长时间才能更新。可能是什么原因?我构建的应用程序正确吗?

BasicRandomApplication.java

package SideActivities;

import javax.swing.SwingUtilities;

public class BasicRandomApplication
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                MainFrame y = new MainFrame();
                RandomNumberLogic x = new RandomNumberLogic();
                x.setListener(y.randomNumberPanel);
                x.generateNumbers();
            }
        });
    }
}

最佳答案

这里listener为空。调用类RandomNumberLogic

的方法setListener()

关于java - 连接 GUI (Swing) 和业务逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29585454/

相关文章:

java - 载体和界面多态性

Java MVC、工厂和观察者模式结合在一起

c++ - 选择要覆盖哪个基类的方法

javascript - ExtJS 4 获取可观察对象的每个监听器

java - 维护插入顺序的并发集合

Java初始化方法

java - 在 Swing 中的 JTable 单元格内滚动

Java:无法重新绘制 ImageIcon

java - Install4j 处理多个屏幕的取消事件

具有 getSize().width、getSize().height 的 Java 小程序