我正在開發一個 RMI 瀏覽器專案。其中有兩個介面Service和ServiceServer。三個類 ServiceServerImpl(Server)、ServiceBrowser(Client) 和 DiceTester。
ServiceBrowser(客戶端)呼叫實作服務(介面)的類 DiceTester,該服務(介面)將序列化的 JPanel 回傳給 ServiceBrowser。
ServiceBrowser 添加了 DiceTester 發送的 JPanel,甚至添加了 JButton 和 JComboxBox,但是當它呼叫 paintComponent 方法時,它不會在 Clients Browser 上繪制任何內容。
服務服務器介面代碼。
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ServiceServer extends Remote {
Object[] getServiceList() throws RemoteException;
Service getService(Object serviceKey) throws RemoteException;
}
服務介面
import javax.swing.*;
import java.io.Serializable;
public interface Service extends Serializable {
JPanel getGUIPane();
}
ServiceServerImpl (服務器)
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
public class ServiceServerImpl extends UnicastRemoteObject implements ServiceServer{
HashMap serviceList;
public ServiceServerImpl() throws RemoteException{
setUpServices();
}
private void setUpServices(){
serviceList = new HashMap();
serviceList.put("New Dice Rolling Serivce", new DiceTester());
}
@Override
public Object[] getServiceList() throws RemoteException {
System.out.println("in remote");
return serviceList.keySet().toArray();
}
@Override
public Service getService(Object serviceKey) throws RemoteException {
return (Service) serviceList.get(serviceKey);
}
public static void main(String[] args) {
try{
Naming.rebind("com.headfirstjava.ServiceServer", new ServiceServerImpl());
//Please remove the package name or change it accordingly.
} catch (Exception Ex){
Ex.printStackTrace();
}
}
}
服務瀏覽器(客戶端)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.Naming;
public class ServiceBrowser {
JPanel mainPanel;
JComboBox serviceList;
ServiceServer server;
private void buildGUI() {
JFrame frame = new JFrame("RMI Browser");
mainPanel = new JPanel();
Object[] services = getServiceList();
serviceList = new JComboBox(services);
serviceList.addActionListener(new MyListListener());
frame.getContentPane().add(BorderLayout.NORTH, serviceList);
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setVisible(true);
}
private Object[] getServiceList() {
Object obj = null;
Object[] services = null;
try {
obj = Naming.lookup("rmi://127.0.0.1/com.headfirstjava.ServiceServer");
////Please remove the package name or change it accordingly.
} catch (Exception ex) {
ex.printStackTrace();
}
server = (ServiceServer) obj;
try {
services = server.getServiceList();
} catch (Exception ex) {
ex.printStackTrace();
}
return services;
}
class MyListListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Object selection = serviceList.getSelectedItem();
loadService(selection);
}
}
private void loadService(Object serviceSelction) {
try {
Service svc = server.getService(serviceSelction);
mainPanel.removeAll();
mainPanel.add(svc.getGUIPane());
mainPanel.validate();
mainPanel.repaint();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
new ServiceBrowser().buildGUI();
}
}
骰子測驗儀
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Objects;
public class DiceTester implements Service {
static final long serialVersionUID = -7720503853902873983L;
int i = 0;
private static final int RECT_Y = 120;
private static final int RECT_HEIGHT = 100;
private static final int RECT_WIDTH = 100;
JPanel mainPanel;
JPanel diceTestPanel;
JComboBox selection;
@Override
public JPanel getGUIPane() {
mainPanel = new JPanel(new BorderLayout());
JPanel componentPanel = new JPanel();
diceTestPanel = new MyDrawPanel();
String[] choices = {"0", "1", "2", "3", "4", "5"};
selection = new JComboBox(choices);
JButton button = new JButton("Roll 'em!");
button.addActionListener(new RollTestListener());
componentPanel.add(selection);
componentPanel.add(button);
mainPanel.add(BorderLayout.NORTH,componentPanel);
diceTestPanel.add(new MyDrawPanel());
mainPanel.add(BorderLayout.CENTER, diceTestPanel);
return mainPanel;
}
class RollTestListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
mainPanel.repaint();
System.out.println("Done");
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
int RECT_X = 10;
String number = (String) selection.getSelectedItem();
Graphics2D g2d = (Graphics2D) g;
for (int x = 0; x < Integer.parseInt(Objects.requireNonNull(number)); x ) {
g2d.setColor(new Color(0x0A0A0A));
g2d.fill3DRect(RECT_X, RECT_Y, RECT_WIDTH, RECT_HEIGHT, true);
int r = (int) ((Math.random() * 6) 1);
switch (r) {
case 1:
g2d.setColor(Color.WHITE);
g2d.fillOval(RECT_X 36, RECT_Y 36, 25, 25);
break;
case 2:
g2d.setColor(Color.WHITE);
g2d.fillOval(RECT_X 20, RECT_Y 36, 25, 25);
g2d.fillOval(RECT_X 55, RECT_Y 36, 25, 25);
break;
case 3:
g2d.setColor(Color.WHITE);
g2d.fillOval(RECT_X 15, RECT_Y 20, 25, 25);
g2d.fillOval(RECT_X 60, RECT_Y 20, 25, 25);
g2d.fillOval(RECT_X 37, RECT_Y 50, 25, 25);
break;
case 4:
g2d.setColor(Color.WHITE);
g2d.fillOval(RECT_X 15, RECT_Y 15, 25, 25);
g2d.fillOval(RECT_X 60, RECT_Y 15, 25, 25);
g2d.fillOval(RECT_X 15, RECT_Y 60, 25, 25);
g2d.fillOval(RECT_X 60, RECT_Y 60, 25, 25);
break;
case 5:
g2d.setColor(Color.WHITE);
g2d.fillOval(RECT_X 15, RECT_Y 15, 20, 20);
g2d.fillOval(RECT_X 60, RECT_Y 15, 20, 20);
g2d.fillOval(RECT_X 37, RECT_Y 37, 20, 20);//CenterDot
g2d.fillOval(RECT_X 15, RECT_Y 60, 20, 20);
g2d.fillOval(RECT_X 60, RECT_Y 60, 20, 20);
break;
case 6:
g2d.setColor(Color.WHITE);
g2d.fillOval(RECT_X 15, RECT_Y 10, 20, 20);
g2d.fillOval(RECT_X 60, RECT_Y 10, 20, 20);
g2d.fillOval(RECT_X 15, RECT_Y 42, 20, 20);//CenterDot
g2d.fillOval(RECT_X 60, RECT_Y 42, 20, 20);//CenterDot
g2d.fillOval(RECT_X 15, RECT_Y 75, 20, 20);
g2d.fillOval(RECT_X 60, RECT_Y 75, 20, 20);
break;
}
RECT_X = 120;
}
System.out.println("paintComponent done");
}
}
}
要運行編譯所有類,讓我們說“類”目錄。
- cmd rmiregistry 并確保它可以訪問這些類。
- 在另一個終端 java ServiceServerImpl。
- 在另一個終端 java ServiceBrowser。
應該按照上面給出的順序打開,否則失敗。

uj5u.com熱心網友回復:
好的,所以,我實際上正在閱讀這本書“Head first java”,那是一個練習。書中也有類似的程式。所以我想通了。@camickr 也建議這樣做。
我們必須getPrefferedSize()按照@camickr 的建議覆寫方法。
public Dimension getPreferredSize(){
return new Dimension(600,300);
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/511836.html
上一篇:數獨Swing/AwtJava
