2017-02-28 4 views
1

MainAppクラスからuserNamesリストを使用しようとするたびにIndexOutOfBoundsExceptionが発生します。しかし、名前がServerControllerクラスのリストに追加されているので、別のクラスで呼び出されたときにリストが空である理由を理解できません。なぜ、ArrayListは空のままですが、別のクラスのオブジェクトをリストに追加するのはなぜですか?

これは、私がかなり長い間解決しようとしているSOの類似の問題をチェックすることからインスタンス化の問題があると思われますが、私は単純にそうすることができません。私は本当に何か提案、TIAを感謝します。

ここには、ユーザーデータ(名前とID)を格納することのみを目的としたユーザークラスがあります。

public class User { 

public User() { 
} 

public ArrayList<String> userNames = new ArrayList<>(); 

public ArrayList<String> getUserNames() { 
    return this.userNames; 
    } 
} 

私のサーバークラスは次のとおりです。userNamesリストに名前を追加しても問題ありません。

public class ServerController { 

    private final Server server; 
    private final User user; 
    private final GameConfig gameConfig; 

    public ServerController(GameConfig gameConfig) { 
    this.gameConfig = gameConfig; 
    this.server = new Server(); 
    this.user = new User(); 
    } 

    public User getUser() { 
     return user; 
    } 
    private class ServerListener extends Listener { 
    //this is where I add the names to the userNames list 
    @Override 
    public void received(Connection connection, Object obj) { 
     server.sendToAllExceptTCP(connection.getID(), obj); 
     if (obj instanceof String) { 
      final String jp = (String) obj; 
      user.userNames.add(jp); 
     } 
} 

私のメインアプリケーションは次のとおりです。userNamesに保存されているユーザーの名前にアクセスしようとしています。名前は、正常に動作する接続が受信されるたびにServerControllerによってリストに追加されますが、createPlayerメソッドで例外が発生します。

public class MainApp { 
public User user = new User(); 

public Game createPlayer(){ 

if (("Mitspieler".equals(client1)) && ("Mitspieler".equals(client2)) && ("Mitspieler".equals(bot1))) { 
     for (int i = 0; i < clients.length; i++) { 
    //this is the source of the exception 
      players[i + 1] = createHumanPlayer(user.getUserNames().get(i), i, restColors[i]); 
     } 
} 
    //.... 
} 

スタックトレース:

Exception in thread "JavaFX Application Thread" 
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 
at java.util.ArrayList.rangeCheck(ArrayList.java:653) 
at java.util.ArrayList.get(ArrayList.java:429) 
at client.MainApp.createPlayer(MainApp.java:265) 
+2

'ServerController'と' MainApp'クラスに2つの異なる 'User'インスタンスがあるように見えます – esin88

+0

' createPlayer'を呼び出す前にあなたのリスト 'userNames'にいくつかのデータを入れる必要があります – Abubakkar

+0

ここで、' ServerController'は ' MainApp'? – niceman

答えて

1

2つのインスタンスを作成します。

public class MainApp { 
    public User user = new User(); // Instance 1 
} 

public class ServerController { 
    private User user; 

    public ServerController(GameConfig gameConfig) { 
     this.user = new User(); // Instance 2 
     ... 
    } 
} 

インスタンス1とインスタンス2はデータを共有しません。インスタンス1は追加された名前を保持し、インスタンス2は追加した名前を保持します。

あなたはその後、Singletonだろう

public class User { 
    private static User USER; 

    public static User getInstance() { 
     if(null == USER) { 
      USER = new User(); 
     } 
     return USER; 
    } 
} 

public class MainApp { 
    public Game createPlayer() { 
     User user = User.getInstance(); 
     List<String> userNames = user.getUserNames(); 
    } 
} 

Userような何かを行うことができ、あなたのコントローラの複数のインスタンスを持つ予定がない場合。ただし、複数のインスタンスがServerControllerの場合は、すべて同じユーザーリストが使用されます。それがあなたが望むものでない場合はServerControllerMainAppを初期化し、同じインスタンスをUserとする必要があります。

+0

MainAppでユーザを宣言するには? パブリックユーザーユーザー。 ? また、なぜこのメソッドをServerControllerに移動したのか、それともエラーですか? – InfoGirl

+0

あなたが正しいです、ServerControllerは間違いでした。私はシングルトンにアクセスする方法も明確にしました。シングルトンが何をしているのか、その限界について理解するために、提供されたリンクに従ってください。 なぜ、 'User'というクラスを作成したいのですか?それはいくつかのユーザー名を保持するのは不思議です。それはすべて同じ名前のユーザであるか同じ名前ですか?すべての名前が格納されていれば、 'MainList'にpublic' ArrayList userNames = new ArrayList <>(); 'を移動し、' User'を削除するだけです。 – cmoetzing

+0

リンクありがとうございます!しかし、いくつかの問題: 1.私はプライベート静的最終ユーザーユーザーをしようとすると、私は、デフォルトのコンストラクタで初期化していないというエラーメッセージが表示されますが、別のインスタンスを作成せずにこれをどのように初期化しますか? 2. getInstance()メソッドを別のクラスから呼び出すことはできません。これは1のためですか? – InfoGirl

0

次の2つの場所でユーザーオブジェクトを作成します。 ServerControllerでは、配列にユーザー名を作成して正常に追加します。次に、MainAppではUserオブジェクトを作成し、その中にはuserNamesがありません。

関連する問題