服务端接口
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);
}
}
}