远程部署服务——Head first java 640(改进原文,采用动态注册)

服务端接口

import java.rmi.*;

public interface ServiceServer extends Remote{
     
    //返回服务存储在HashMap中的key
    Object[] getServiceList() throws RemoteException;

    //利用key寻得服务端中的服务将其返回
    Service getService(Object serviceKey) throws RemoteException;
}

服务器接口

import javax.swing.*;
import java.io.*;

//将服务接口设置为可序列化才可进行网络之间的传递
public interface Service extends Serializable{
     
    public JPanel getGuiPanel();
}

服务端实现(动态注册的实现)

import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.util.*;
import java.rmi.server.*;

public class ServiceServerImpl extends UnicastRemoteObject implements ServiceServer{
     

    //存储服务
    HashMap serviceList;

    //父类UnicastRemoteObject会抛出异常所以子类的构造也要抛出异常
    public ServiceServerImpl() throws RemoteException{
     
        setUpService();
    }

    private void setUpService(){
     
        serviceList = new HashMap();
        serviceList.put("Dice Rolling Service",new DiceService());
        serviceList.put("Day of the Week Service",new DayOfTheWeekService());
        serviceList.put("Visual Music Service",new MiniMusiceService());
    }


    @Override
    public Service getService(Object serviceKey) throws RemoteException {
     
        //通过key获取服务
        Service svc = (Service) serviceList.get(serviceKey);
        return svc;
    }

    public Object[] getServiceList() throws RemoteException{
     
        //获得hashmap的key,toArray只能形成Object类型
        return serviceList.keySet().toArray();
    }

    public static void main(String[] args) {
     
        try{
     
            ServiceServerImpl imp = new ServiceServerImpl();

            //jdk5后就是用动态注册了,注册59218端口(服务机器的端口)
            LocateRegistry.createRegistry(5000);
            Naming.rebind("rmi://127.0.0.1:5000/ServiceServer",imp);
        }catch(Exception ex){
     
            ex.printStackTrace();
        }
        System.out.println("Remote service is running");
    }
}

服务器的实现

import java.awt.*;
import javax.swing.*;
import java.rmi.*;
import java.awt.*;
import java.awt.event.*;

public class ServiceBrowser {
     
    JPanel mainPanel;
    JComboBox serviceList;
    ServiceServer server;

    public void buildGui(){
     
        JFrame frame = new JFrame("RMI Browser");
        mainPanel = new JPanel();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //关闭窗口程序随之结束
        frame.getContentPane().add(BorderLayout.CENTER,mainPanel);

        Object[] services = getServiceList(); //取得key
        serviceList = new JComboBox(services);

        frame.getContentPane().add(BorderLayout.NORTH,serviceList);
        serviceList.addActionListener(new MyListener());

        frame.setSize(500,500);
        frame.setVisible(true);
    }

    //取得服务端服务的key以及查询服务端
    Object[] getServiceList(){
     
        Object[] service = null;

        try{
     
            //用的本机地址可自行更改
            server = (ServiceServer)Naming.lookup("rmi://127.0.0.1:5000/ServiceServer");
        }catch(Exception ex){
     
            ex.printStackTrace();
        }

        try{
     
            service = server.getServiceList();  //取得key
        }catch(Exception ex){
     
            ex.printStackTrace();
        }

        return service;
    }

    class MyListener implements ActionListener{
     
        public void actionPerformed(ActionEvent event){
     
            Object selection = serviceList.getSelectedItem();
            loadService(selection);
        }
    }

    public void loadService(Object selection){
     
        try{
     
            Service svc = server.getService(selection); //取得服务

            //选择完后清除所有组件,然后再加入服务的panel,重构画面
            mainPanel.removeAll();
            mainPanel.add(svc.getGuiPanel());
            mainPanel.validate();
            mainPanel.repaint();
        }catch(Exception ex){
     
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
     

        new ServiceBrowser().buildGui();
    }
}

音乐功能

import javax.sound.midi.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

//继承接口实现可序列化
public class MiniMusiceService implements Service{
     
    MyDrawPanel myPanel;

    public JPanel getGuiPanel(){
     
        JPanel mainPanel = new JPanel();
        myPanel = new MyDrawPanel();
        JButton playItButton = new JButton("Play it");
        playItButton.addActionListener(new PlayItListener());
        mainPanel.add(playItButton);
        return mainPanel;
    }

    public class PlayItListener implements ActionListener{
     
        public void actionPerformed(ActionEvent event){
     
            try{
     
                Sequencer sequencer = MidiSystem.getSequencer();
                sequencer.open();

                //当频道为127时触发事件
                Sequence seq = new Sequence(Sequence.PPQ,4);
                Track track = seq.createTrack();

                for(int i=0;i<100;i+=4){
     

                    int rNum = (int)(Math.random()*50+1);
                    if(rNum<38){
      //只有38以下的节拍
                        track.add(makeEvent(144,1,rNum,100,i));

                        //音量为0,不会输出任何声音,他的节拍也与前一节拍相同,声音同时发出
                        //它只是用于被监听者捕获产生图形的中介
                        track.add(makeEvent(176,1,127,0,i));
                        track.add(makeEvent(128,1,rNum,100,i+1));
                    }
                }

                sequencer.setSequence(seq);
                sequencer.start();
                sequencer.setTempoInBPM(220);
            }catch(Exception ex){
     
                ex.printStackTrace();
            }
        }
    }

    public MidiEvent makeEvent(int comd,int chan,int one,int two,int tick){
     
        MidiEvent event = null;
        try{
     
            ShortMessage a = new ShortMessage();
            a.setMessage(comd,chan,one,two);
            event = new MidiEvent(a,tick);

        }catch(Exception ex){
     
            ex.printStackTrace();
        }

        return event;
    }

    class MyDrawPanel extends Panel implements ControllerEventListener{
     
        boolean msg = false;

        public void controlChange(ShortMessage event){
     
            msg = true;
        }

        //返回宽和高给repaint构造panel
        public Dimension getPreferredSize(){
     

            return new Dimension(300,300);
        }

        public void paintComponent(Graphics graphics){
     
            if(msg == true){
     
                Graphics2D g2d = (Graphics2D)graphics;

                int r = (int)(Math.random()*255);
                int g = (int)(Math.random()*255);
                int b = (int)(Math.random()*255);

                g2d.setColor(Color.BLUE);

                int ht = (int)((Math.random()*120)+10);
                int width = (int)((Math.random()*120)+10);
                int x = (int)((Math.random()*40)+10);
                int y = (int)((Math.random()*40)+10);
                int ff = (int)(Math.random()*100);
                if(ff%2 == 0)
                    g2d.fillRect(x,y,width,ht);
                else
                    g2d.fillOval(x,y,width,ht);
                msg = false;
            }
        }
    }
}

查询星期功能

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.text.*;

//继承接口使其可序列化
public class DayOfTheWeekService implements Service {
     

    JLabel outputLabel;
    JComboBox month;
    JTextField day;
    JTextField year;

    public JPanel getGuiPanel() {
     
        DateFormatSymbols dateStuff = new DateFormatSymbols();
        month = new JComboBox(dateStuff.getMonths());  //获取十二个月份作为选项
        day = new JTextField(8); //只有一行 8字宽
        year = new JTextField(8); //同上
        JPanel panel = new JPanel();
        JButton button = new JButton("Do it!");
        button.addActionListener(new DoItListener());
        outputLabel = new JLabel("date appears here!");
        JPanel inputPanel = new JPanel(new GridLayout(3,2));
        inputPanel.add(new JLabel("Month"));
        inputPanel.add(month);
        inputPanel.add(new JLabel("Day"));
        inputPanel.add(day);
        inputPanel.add(new JLabel("Year"));
        inputPanel.add(year);
        panel.add(inputPanel);
        panel.add(button);
        panel.add(outputLabel);
        return panel;
    }

    class DoItListener implements ActionListener {
     
        public void actionPerformed(ActionEvent event) {
     
            int mothNum = month.getSelectedIndex();
            int dayNum = Integer.parseInt(day.getText());
            int yearNum = Integer.parseInt(year.getText());
            Calendar c = Calendar.getInstance();

            c.set(Calendar.MONTH, mothNum);
            c.set(Calendar.YEAR, yearNum);
            c.set(Calendar.DAY_OF_MONTH, dayNum);  //设置年月日

            Date date = c.getTime();

            //设置字符串格式,E代表星期几
            String dayOfWeek = (new SimpleDateFormat("EEEE")).format(date);
            outputLabel.setText(dayOfWeek);
        }
    }
}

选择次数扔骰子功能

import javax.swing.*;
import java.awt.event.*;
import java.io.*;

//继承接口使其可序列化
public class DiceService implements Service{
     
    JLabel label;
    JComboBox numOfDice;

    public JPanel getGuiPanel(){
     
        JPanel panel = new JPanel();
        JButton button = new JButton("Roll 'em'!");
        String[] choices={
     "1","2","3","4","5"}; //扔骰子次数
        numOfDice = new JComboBox(choices);
        label = new JLabel("dice values here");
        button.addActionListener(new RollEmListener());
        panel.add(numOfDice);
        panel.add(button);
        panel.add(label);

        return panel;
    }

    class RollEmListener implements ActionListener{
     
        public void actionPerformed(ActionEvent event){
     
            String diceOutput="";
            String selection = (String)numOfDice.getSelectedItem();
            int numOfDiceToRoll = Integer.parseInt(selection);
            for(int i=0;i<numOfDiceToRoll;i++){
     
                int r = (int)(Math.random()*6+1);
                diceOutput+=(" "+r);
            }
            label.setText(diceOutput);
        }
    }
}

静态已成过去
远程部署服务——Head first java 640(改进原文,采用动态注册)_第1张图片

你可能感兴趣的:(远程部署服务——Head first java 640(改进原文,采用动态注册))