我是JAVA和我的大学项目的新手,我必须编写一个RMI应用程序。
我编写了一个服务器类,一个客户端类和一个JFrame类。
服务器和客户端之间的连接正在运行,并且我可以在它们之间进行通信。
为了可视化客户端(现在是JFrame类的子代),我已经对上面提到的JFrame类进行了编码。 在这个JFrame类中,我实例化了客户端。
现在,让我们终于解决了我的问题:
我在服务器类中调用方法A,它在客户端中调用方法B,并且此方法B应该在JFrame类中调用方法C.具体来说,我想在JFrame类的JTextArea中追加一个String,但这不起作用。这是代码。非常感谢提前。
服务器代码:
import java.io.Serializable;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JTextArea;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Sebbo
*/
public class ServerImpl implements IServer, Serializable {
public static ArrayList<IClient> spielerliste = new ArrayList();
public static ArrayList<IClient> readyListe = new ArrayList();
private ArrayList benutzernamen = new ArrayList();
private ServerFenster serverfenster;
private int anzahlKarten = 7;
ArrayList<Card> kartendeck;
/*
public ServerImpl(ServerFenster serverFenster) {
this.serverfenster = serverFenster;
}
*/
public ServerImpl() {
}
@Override
public void clientAnmelden(String benutzername, String clientIndex) throws NotBoundException, RemoteException, AccessException{
System.out.println(benutzername + " beim Spiel angemeldet!");
benutzernamen.add(benutzername);
for (int i = 0; i < benutzernamen.size(); i++ ) {
System.out.println(benutzernamen.get(i).toString());
}
//Find Client
Registry registry = LocateRegistry.getRegistry();
IClient tmpClient = (IClient) registry.lookup( clientIndex );
spielerliste.add(tmpClient);
//serverfenster.jPanelHinzufuegen(benutzername);
}
@Override
public void spielStarten(ArrayList<IClient> readyliste) throws RemoteException {
kartendeck = Card.kartendeckErzeugen();
this.kartenAnSpielerVerteilen(readyliste);
}
@Override
public void spielerlisteAnzahlAusgeben() throws RemoteException {
System.out.println(this.spielerliste.size());
}
@Override
public ArrayList<IClient> spielerlisteAusgeben() throws RemoteException {
return this.spielerliste;
}
/**
*
* @param IClient
*/
public void kartenAnSpielerVerteilen(ArrayList<IClient> readyliste) throws RemoteException {
for (int i = 0; i < readyliste.size(); i++) {
readyliste.get(i).handNehmen(kartendeck, anzahlKarten);
readyliste.get(i).handAusgeben();
System.out.println("Hand ausgeteilt.");
}
}
@Override
public void readyListeChecken() throws RemoteException {
// spielerliste durchgehen und Spieler, die bereit sind, in ReadyListe verschieben
for (int i = 0; i < spielerliste.size(); i++) {
if (spielerliste.get(i).getSpielerstatus()) {
IClient tmpClient = spielerliste.get(i);
spielerliste.remove(spielerliste.get(i));
readyListe.add(tmpClient);
}
}
int anzahlBereiterSpieler = 0;
for (int i = 0; i < readyListe.size(); i++) {
if (readyListe.get(i).getSpielerstatus()) {
anzahlBereiterSpieler++;
}
}
if (anzahlBereiterSpieler < 2) {
System.out.println("Anzahl bereiter Spieler: " + anzahlBereiterSpieler);
} else {
System.out.println("Anzahl bereiter Spieler: " + anzahlBereiterSpieler);
System.out.println("Spiel wird gestartet.");
spielStarten(this.readyListe);
}
anzahlBereiterSpieler = 0;
}
public void broadcastMessage(String message) throws RemoteException {
System.out.println(message);
for(int i =0; i<spielerliste.size(); i++) {
spielerliste.get(i).nachrichtEmpfangen(message);
}
}
}
客户代码:
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JTextArea;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Sebbo
*/
public class ClientImpl extends ClientFenster implements IClient, Serializable {
private static final long serialVersionUID = 1L;
//private ArrayList<Card> cards;
private IServer server;
private IClient client;
private String benutzername;
private ArrayList<Card> hand;
private boolean spielerBereit = true;
private boolean spielerAmZug = false;
private static int clientIndex = 0;
public ClientImpl(IServer server, String benutzername) throws Exception{
this.hand = new ArrayList();
this.benutzername = benutzername;
this.server = server;
this.server.clientAnmelden(this.benutzername, registerClient());
}
@Override
public void handNehmen(ArrayList<Card> kartendeck, int anzahlKarten) {
for (int i = 0; i < anzahlKarten; i++) {
this.hand.add(kartendeck.get(0));
kartendeck.remove(kartendeck.get(0));
}
}
int playerIndex;
private String registerClient() throws RemoteException{
//Search in all registry keys
//last clientXX +1
String key = "Client" + clientIndex++;
client = (IClient) UnicastRemoteObject.exportObject( this, 0 );
Registry registry = LocateRegistry.getRegistry();
int index = 0;
registry.rebind(key, client );
return key;
}
private int getNumberOfPlayers(){
String keyNumOfPlayers = "playerIndex";
//Registry=> playerIndex:int
return -1;
}
private void setNumberOfPlayers(){
//Registry <= playerIndex:int
}
@Override
public void handAusgeben() throws RemoteException{
for (Card karte : hand) {
System.out.println(karte.getFarbe() + " - " + karte.getWert() + " - " + karte.getID());
}
}
@Override
public String getBenutzername() throws RemoteException{
return this.benutzername;
}
@Override
public boolean getSpielerstatus() throws RemoteException{
return this.spielerBereit;
}
@Override
public void bereitMelden() throws RemoteException{
this.spielerBereit = true;
this.server.readyListeChecken();
}
@Override
public boolean getSpielerAmZug() throws RemoteException{
return this.spielerAmZug;
}
@Override
public void setSpielerAmZugTrue() throws RemoteException {
this.spielerAmZug = true;
}
@Override
public void setSpielerAmZugFalse() throws RemoteException {
this.spielerAmZug = false;
}
/*
Methode, die wartet, vom Server ausgelöst zu werden und dann eine Nachricht übermittelt und zurückgibt.
*/
/**
*
* @param message
* @throws RemoteException
*/
public void nachrichtEmpfangen(String message) throws RemoteException {
// Code
nachrichtInTextAreaEinfuegen(message);
}
public IServer getServer() {
return this.server;
}
}
JFrame代码:
import java.awt.event.KeyEvent;
import java.io.Serializable;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTextArea;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Sebbo
*/
public class ClientFenster extends javax.swing.JFrame {
private static IClient client;
static int playerIndex = 0;
private static ClientImpl clientImpl;
private ClientFenster fenster = this;
/**
* Creates new form ClientFenster
*/
public JTextArea getJTextArea2() {
return jTextArea2;
}
public ClientFenster() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea2 = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("Hand ausgeben");
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jTextArea1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jTextArea1KeyReleased(evt);
}
});
jScrollPane1.setViewportView(jTextArea1);
jTextArea2.setColumns(20);
jTextArea2.setRows(5);
jScrollPane2.setViewportView(jTextArea2);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jScrollPane2)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton1)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap(178, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(50, 50, 50)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 232, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jTextArea1KeyReleased(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode()==KeyEvent.VK_ENTER){
Date d1 = new Date();
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss ");
String formattedDate = df.format(d1);
try {
clientImpl.getServer().broadcastMessage("[" + formattedDate + "] " + clientImpl.getBenutzername() +": " + jTextArea1.getText());
} catch (RemoteException ex) {
Logger.getLogger(ClientFenster.class.getName()).log(Level.SEVERE, null, ex);
}
jTextArea1.setText(null);
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) throws RemoteException, NotBoundException, Exception {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ClientFenster.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ClientFenster.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(ClientFenster.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ClientFenster.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ClientFenster().setVisible(true);
}
});
Registry registry = LocateRegistry.getRegistry();
IServer server = (IServer) registry.lookup( "Server" );
String benutzername = "Tim";
clientImpl = new ClientImpl(server, benutzername);
}
/*public Client() {
this.client = (IClient) new Client();
}*/
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
private javax.swing.JTextArea jTextArea2;
// End of variables declaration
/**
*
* @param message
*/
public void nachrichtInTextAreaEinfuegen(String message) {
jTextArea2.append(message);
jTextArea2.revalidate();
jTextArea2.repaint();
}
}
很多,很多人提前感谢并抱歉我的错误代码和英语; - )
答案 0 :(得分:0)
问题已经解决了。一切正常,但JTextArea没有自动滚动,因此代码在第一行上方附加了字符串,并且它不可见。
一位朋友用插入来修复它:
jTextArea2.setCaretPosition(jTextArea2.getText().length() - 1);
感谢您的帮助,我将来会尝试以更好的方式发布。遗憾。