java属性变化事件机制(2)

来源:互联网 发布:淘宝买的东西不合适 编辑:程序博客网 时间:2024/06/03 17:19

 

    如果需要处理大量的属性又怎么样呢?

    想象这样一种场景:

    要在屏幕上显示远程交换机(或者路由器)的前后面板的各组件(交换机完整照片分割成可管理的拼图)特别是显示灯的情况,这样用户就不用走到交换机所在的地方,就可以监控到交换机的运行情况。交换机的各个灯都有其意义,电源灯,端口灯……运行的并正常的端口亮绿点,shutdown的不亮灯,有故障的亮红灯等……除了灯还要显示交换机的模块(如果有),风扇运转情况等。

    一般情况下,都是定义一个属性对应一个显示组件,如:

    Fast_0_0_1:模块0第一个端口

    Fast_0_0_2:模块0第二个端口

    Fast_0_1_1:模块1第一个端口

    PIC_0_0:端口模块0

    PIC_0_1:端口模块1

    Power:电源灯

    ……几十个属性。

 

每个显示的组件又对应一个JPanel(或者JLabel)。如一个端口是一个JPanel,一个模块也是一个JPanel,几个端口包含在一个模块中。模块又包含在大的背景面板中……

 

   如果这些属性分散到各个组件类中,将难于管理的,因此有大量属性时应该有一个统一的属性管理器,将有变化的属性保存到属性管理器中统一管理。

 

    项目中的一个模块就是用一个属性管理器来管理属性变化的,将远程监控的设备运行情况真实地显示出来。但是其属性事件机制感觉比较复杂,不利于新手理解学习,我也是新手,所以参考其实现机制,按照自己的理解,以简单的方法去实现大量属性的管理。

 

先了解学习下java的一个组件:

 

public class UIDefaults

extends Hashtable<Object,Object>

Swing 组件的默认值表。应用程序可以通过

UIManager

设置/获取默认值。

其中的方法:put

public Object put(Object key,

                  Object value)

将 key 值设置为所有语言环境的 value。如果 key 为一个字符串且新值不等于旧值,则触发一个 PropertyChangeEvent。如果值为 null,则从表中移除该键。

 

 

     不过这个练习不使用UIDefaults,下面是自己写的练习,模拟交通信息面板。

 

     主要是定义一个属性管理类PropertyManage,包含增加或移除属性,事件的方法,响应事件的方法等,如:

     //维护属性与事件列表

    private static HashMap<String, TrafficListener> listenerList = null;

    //维护属性与值的表

    private static HashMap<String, String>  propertyList = null;

    /**

     * 注册属性名,属性值,属性的事件

     * @param propertyName 属性名

     * @param propertyValue 属性值

     * @param listener 属性对应的事件

     */

    public static void addPropListener(String propertyName,

                                   String propertyValue,

                                   TrafficListener listener)

 

    /**

     * 响应事件。

     * @param propertyName 属性名

     * @param propertyValue 属性值

     */

    public static void change(String propertyName, String propertyValue)

 

注册属性及事件,如:

PropertyManage.addPropListener("redLED", "off", red);//red是实现监听类TrafficListener的自定义组件

属性变化响应事件,如:

PropertyManage.change("redLED", "on");//原来是off,现在值变为on,触发事件。

 

 

如下图,交通信息面板就是由几个label,button,panel组成的,每一个组件都与一个属性及事件关联。只要在控制台选择属性,再输入属性值,点击send,即可看到交通信息面板相应变化(变化要自己实现)。图中的label,button,panel都实现类TrafficListener:

public interface TrafficListener extends EventListener

{

    public void onPropertyChange(TrafficEvent event);

 

}

 

 

上图中,当trafficLight=on时,左侧的红黄绿灯则来亮起来,trafficLight=off,则会停止亮灯。其它组件只是设值,没有过多地实现。

 

实现代码如下:

package cn.com.cathay.event.traffic.manage;

 

import java.util.HashMap;

import java.util.Set;

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

import cn.com.cathay.event.traffic.listener.TrafficListener;

 

/**

 * 属性变化的事件管理类。

 * 局限:

 * 1.一个属性不能响应一个以上的事件。

 * @author luolihui

 *

 */

public class PropertyManage

{

    private static HashMap<String, TrafficListener> listenerList = null;

   

    private static HashMap<String, String>  propertyList = null;

   

    /**

     * 注册属性名,属性值,属性的事件

     * @param propertyName 属性名

     * @param propertyValue 属性值

     * @param listener 属性对应的事件

     */

    public static void addPropListener(String propertyName,

                                       String propertyValue,

                                       TrafficListener listener)

    {

        addProperty(propertyName, propertyValue);

        addTrafficListener(propertyName, listener);

    }

   

    /**

     * 注册属性名和属性值

     * @param propertyName 属性名

     * @param propertyValue 属性值

     */

    public static void addProperty(String propertyName, String propertyValue)

    {

        if (propertyList == null)

        {

            propertyList = new HashMap<String, String>();

        }

        propertyList.put(propertyName, propertyValue);

    }

   

    /**

     * 注册属性名及对应的事件

     * @param propertyName 属性名

     * @param listener 属性事件

     */

    public static void addTrafficListener(String propertyName,

                                          TrafficListener listener)

    {

        if (listenerList == null)

        {

            listenerList = new HashMap<String, TrafficListener>();

        }

       

        listenerList.put(propertyName,listener);       

    }

   

    /**

     * 获得该类维护的所有属性名。

     * @return 该类维护的所有属性名。

     */

    public static Set<String> getPropertyNames()

    {

        if (propertyList == null)

        {

            return null;

        }

        else

        {

            return propertyList.keySet();

        }

    }

   

    /**

     * 将以该属性名propertyName注册的值和事件移除。

     * @param propertyName 属性名

     */

    public static void removeTrafficListener(String propertyName)

    {

        if (listenerList != null)

        {

            listenerList.remove(propertyName);

        }

       

        if (propertyList != null)

        {

            propertyList.remove(propertyName);

        }

    }

   

    /**

     * 响应事件。

     * @param propertyName 属性名

     * @param propertyValue 属性值

     */

    public static void change(String propertyName, String propertyValue)

    {

        String oldValue = null;

        String newValue = propertyValue;

       

        TrafficListener listener = listenerList.get(propertyName);

        if ( listener == null)

        {

            addProperty(propertyName, newValue);

            return;

        }

       

        oldValue = propertyList.get(propertyName);

        if (oldValue == null && newValue == null)

        {

            return;

        }

       

        if(oldValue == null || !oldValue.equals(newValue))

        {

            addProperty(propertyName, newValue);

            fireOnPropertyChange(newValue, listener);

        }

    }

   

    /**

     *

     * @param newValue

     * @param listener

     */

    private static void fireOnPropertyChange(String newValue,

                                             TrafficListener listener)

    {

        TrafficEvent event = new TrafficEvent(listener, newValue);

        listener.onPropertyChange(event);

    }

 

 

}

 

package cn.com.cathay.event.traffic.event;

 

import java.util.EventObject;

 

public class TrafficEvent extends EventObject

{

    private String value = null;

   

    public TrafficEvent(Object source, String value)

    {

        super(source);

        this.value = value;

    }

 

    /**

     * @return the value

     */

    public String getValue() {

        return value;

    }

 

    /**

     * @param value the value to set

     */

    public void setValue(String value) {

        this.value = value;

    }

 

}

 

package cn.com.cathay.event.traffic.listener;

 

import java.util.EventListener;

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

 

public interface TrafficListener extends EventListener

{

         public void onPropertyChange(TrafficEvent event);

 

}

 

package cn.com.cathay.event.traffic.view;

 

import java.awt.Color;

 

import javax.swing.JButton;

 

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

import cn.com.cathay.event.traffic.listener.TrafficListener;

 

public class LEDButton extends JButton implements TrafficListener

{

    private Color       onColor;     // ON状態色(正常)

    private Color       offColor;          // 通電していない状態色(異常)

   

    public LEDButton(Color onColor, Color offColor)

    {

    this.onColor = onColor;

    this.offColor = offColor;

   

    this.setBackground(Color.LIGHT_GRAY);

    }

   

    public Color getOnColor()

    {

    return onColor;

    }

   

    public Color getOffColor()

    {

    return offColor;

    }

 

         /**

          * @param onColor the onColor to set

          */

         public void setOnColor() {

                   this.setBackground(this.onColor);

         }

 

         /**

          * @param offColor the offColor to set

          */

         public void setOffColor() {

                   this.setBackground(this.offColor);

         }

        

 

    public void onPropertyChange(TrafficEvent event)

    {

//             TrafficLight light = (TrafficLight)event.getSource();

    

    String value = event.getValue();

   

    if ("on".equals(value))

    {

               setOnColor();

    }

    else if ("off".equals(value))

    {

               setOffColor();

    }

    }

}

 

package cn.com.cathay.event.traffic.view;

 

import java.awt.Color;

import java.awt.GridLayout;

 

import javax.swing.JPanel;

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

import cn.com.cathay.event.traffic.listener.TrafficListener;

import cn.com.cathay.event.traffic.manage.PropertyManage;

 

public class TrafficLightPanel extends JPanel implements TrafficListener

{

         JPanel trafficLight = null;

         boolean isRun = true;

         LEDButton red;

         LEDButton yellow;

         LEDButton green;

        

         public TrafficLightPanel()

         {

                   setLayout(new GridLayout(3,1));

                   init();

                  

         }

        

         public void init()

         {

                   red = new LEDButton(Color.red, Color.LIGHT_GRAY);

                   yellow = new LEDButton(Color.yellow, Color.LIGHT_GRAY);

                   green = new LEDButton(Color.green, Color.LIGHT_GRAY);

                  

                   add(red);

                   add(yellow);

                   add(green);

                  

                   //注册属性和事件

                   PropertyManage.addPropListener("redLED", "off", red);

                   PropertyManage.addPropListener("greenLED", "off", green);

                   PropertyManage.addPropListener("yellowLED", "off", yellow);

 

         }

        

         /**

          * 属性变化的响应事件方法

          */

         public void onPropertyChange(TrafficEvent event)

         {

                   String status = event.getValue();

                  

                   if ("on".equals(status))

                   {

                            isRun = true;

                            new Worker().start();  

                   }

                   else if ("off".equals(status))

                   {

                            isRun = false;

                   }

         }

        

         public void change()

         {

                   //可直接使用red.setBackground();

                  PropertyManage.change("redLED", "on");

                   PropertyManage.change("greenLED", "off");

                   sleep(1000l);

                  

                   PropertyManage.change("redLED", "off");

                   PropertyManage.change("yellowLED", "on");

                   sleep(1000l);

 

                   PropertyManage.change("yellowLED", "off");

                   PropertyManage.change("greenLED", "on");

                   sleep(1000l);

         }

        

         /**

          * 休眠

          * @param time

          */

         public void sleep(long time)

         {

                   try {

                            Thread.sleep(time);

                   } catch (InterruptedException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                   }

         }

        

         /**

          * 工作线程

          * @author luolihui

          *

          */

         public class Worker extends Thread

         {

                   public void run()

                   {

                            while(isRun)

                            {

                                     change();

                            }

                           

                            PropertyManage.change("greenLED", "off");

                            PropertyManage.change("redLED", "off");

                            PropertyManage.change("yellowLED", "off");

 

                   }

         }

}

 

package cn.com.cathay.event.traffic.view;

 

import javax.swing.JLabel;

 

import cn.com.cathay.event.traffic.listener.TrafficListener;

import cn.com.cathay.event.traffic.event.TrafficEvent;

 

public class DateLabel extends JLabel implements TrafficListener

{

         public DateLabel()

         {

                   this.setText("date");

         }

        

    public void onPropertyChange(TrafficEvent event)

    {

    DateLabel date = (DateLabel)event.getSource();

   

    date.setText(event.getValue());

    }

}

package cn.com.cathay.event.traffic.view;

 

import javax.swing.JLabel;

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

import cn.com.cathay.event.traffic.listener.TrafficListener;

 

public class WeekLabel extends JLabel implements TrafficListener

{

         public WeekLabel()

         {

                   this.setText("week");

         }

        

         public void onPropertyChange(TrafficEvent event)

    {

                   WeekLabel week = (WeekLabel)event.getSource();

                   week.setText(event.getValue());

    }

}

package cn.com.cathay.event.traffic.view;

 

import javax.swing.JLabel;

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

import cn.com.cathay.event.traffic.listener.TrafficListener;

 

public class WeatherLabel extends JLabel implements TrafficListener

{

         public WeatherLabel()

         {

                   this.setText("weather");

         }

        

         public void onPropertyChange(TrafficEvent event)

    {

    WeatherLabel weather = (WeatherLabel)event.getSource();

    weather.setText(event.getValue());

    }

}

 

package cn.com.cathay.event.traffic.view;

 

import javax.swing.JLabel;

 

import cn.com.cathay.event.traffic.event.TrafficEvent;

import cn.com.cathay.event.traffic.listener.TrafficListener;

 

public class TipLabel extends JLabel implements TrafficListener

{

         public TipLabel()

         {

                   this.setText("请遵守交通规则");

         }

        

         public void onPropertyChange(TrafficEvent event)

    {

                   TipLabel tip = (TipLabel)event.getSource();

                  

                   tip.setText(event.getValue());

    }

}

 

package cn.com.cathay.event.traffic.view;

 

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.FlowLayout;

import java.awt.GridLayout;

 

import javax.swing.BorderFactory;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

 

import cn.com.cathay.event.traffic.manage.PropertyManage;

 

/**

 * 交通信息面板类。

 * @author luolihui

 *

 */

public class TrafficPanel extends JFrame

{

         public TrafficPanel()

         {

                   setTitle("交通信息面板");

                   setLayout(new BorderLayout());

                   setSize(300, 150);

                   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                   setResizable(false);

                  

                   init();

         }

        

         /**

          * 初始化面板

          */

         public void init()

         {

                  

                   add(addTrafficLight(),BorderLayout.WEST);

                  

                   JPanel rightPanel = new JPanel(new GridLayout(3,1));

                   add(rightPanel);

                  

                   rightPanel.add(addDateWeek());

                   rightPanel.add(addWeather());

                   rightPanel.add(addTip());

                  

                   setVisible(true);

         }

        

         /**

          * 增加红绿灯面板

          * @return

          */

         public JPanel addTrafficLight()

         {

                   TrafficLightPanel trafficLight;

                   trafficLight = new TrafficLightPanel();

                   PropertyManage.addPropListener("trafficLight", null, trafficLight);

//                 trafficLight.setSize(100, 150);

//                 JPanel trafficLight  = new JPanel(new GridLayout(3,1));

//                 LEDButton red = new LEDButton(Color.red, Color.LIGHT_GRAY);

//                 LEDButton yellow = new LEDButton(Color.yellow, Color.LIGHT_GRAY);

//                 LEDButton green = new LEDButton(Color.green, Color.LIGHT_GRAY);

//                

//                 trafficLight.add(red);

//                 trafficLight.add(yellow);

//                 trafficLight.add(green);

//                

//                 //注册属性和事件

//                 PropertyManage.addPropListener("redLED", "off", red);

//                 PropertyManage.addPropListener("greenLED", "off", green);

//                 PropertyManage.addPropListener("yellowLED", "off", yellow);

//

//                 return trafficLight;

                  

                   return trafficLight;

         }

        

         /**

          * 增加日期,星期面板

          * @return

          */

         public JPanel addDateWeek()

         {

                   JPanel dateWeelLabel = new JPanel(new FlowLayout());

                   dateWeelLabel.add(addDate());

                   dateWeelLabel.add(addWeel());

                   dateWeelLabel.setBorder(BorderFactory.createLineBorder(Color.red));

                   return dateWeelLabel;

         }

        

         /**

          * 增加日期

          */

         public JLabel addDate()

         {

                   DateLabel dateLabel = new DateLabel();

                   PropertyManage.addPropListener("date", null, dateLabel);

                   return dateLabel;

         }

        

         /**

          * 增加星期

          * @return

          */

         public JLabel addWeel()

         {

                   WeekLabel weelLabel = new WeekLabel();

                   PropertyManage.addPropListener("week", null, weelLabel);               

                   return weelLabel;

         }

        

         /**

          * 增加天气情况面板

          * @return

          */

         public JPanel addWeather()

         {

                   JPanel weatherPanel = new JPanel(new FlowLayout());

                   WeatherLabel weatherLabel = new WeatherLabel();

                   weatherPanel.add(weatherLabel);

                   weatherPanel.setBorder(BorderFactory.createLineBorder(Color.yellow));

                  

                   PropertyManage.addPropListener("weather", null, weatherLabel);

        

                   return weatherPanel;

         }

        

         /**

          * 增加宣传标语面板

          * @return

          */

         public JPanel addTip()

         {

                   JPanel tipPanel = new JPanel();

                   TipLabel tipLabel = new TipLabel();

                   tipPanel.add(tipLabel);

                   tipPanel.setBorder(BorderFactory.createLineBorder(Color.green));

                  PropertyManage.addPropListener("tip", null, tipLabel);

                   return tipPanel;

         }

        

         public static void main(String[] args)

         {

                   new TrafficPanel();

         }

}

package cn.com.cathay.event.traffic.view;

 

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.Iterator;

import java.util.Set;

 

import javax.swing.JButton;

import javax.swing.JComboBox;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTextField;

 

import cn.com.cathay.event.traffic.manage.PropertyManage;

 

/**

 * 交通信息面板控制台

 * @author luolihui

 *

 */

public class ControllPanel extends JFrame implements ActionListener

{

         private JComboBox propNameBox;

         private JTextField propValueField;

        

         public ControllPanel()

         {

                   setTitle("交通面板控制台");

                   setSize(230, 100);

                   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                   setResizable(false);

                   init();

         }

        

         /**

          * 初始化面板组件

          */

         public void init()

         {

                   JPanel contrPanel = new JPanel(new BorderLayout());

                  

                   propValueField = new JTextField(10);

                   propValueField.setToolTipText("请输入属性的值");

                   JButton sendButton = new JButton("send");

                   sendButton.addActionListener(this);

                  

                   contrPanel.add(addPropertyBox(), BorderLayout.NORTH);

                   contrPanel.add(propValueField, BorderLayout.CENTER);

                   contrPanel.add(sendButton, BorderLayout.SOUTH);

                   add(contrPanel);

                   setVisible(true);

         }

        

         /**

          * 增加属性名

          * @return

          */

         public JComboBox addPropertyBox()

         {

                   propNameBox = new JComboBox();

                   propNameBox.addItem("请选择属性名并在下栏输入属性值");

                  

                   Set<String> names = PropertyManage.getPropertyNames();     

                  

                   if (names != null)

                   {

                            Iterator<String> it = names.iterator();    

                            while(it.hasNext())

                            {

                                     propNameBox.addItem(it.next());

                            }

                   }

                  

                   return propNameBox;

         }

        

    /**

     * 响应发送按钮事件。调用属性管理器即可。

     */

         public void actionPerformed(ActionEvent event)

         {

                   PropertyManage.change((String)propNameBox.getSelectedItem(),

                                                                   propValueField.getText());

         }

        

         public static void main(String[] args)

         {

                   new ControllPanel();

         }

}

 

package cn.com.cathay.event.traffic.view;

/**

 *

 * @author luolihui

 *

 */

public class MainStart

{

 

    public static void main(String[] args)

    {

        new TrafficPanel();

        new ControllPanel();

    }

}

 

0 0
原创粉丝点击