0

処理に oscP5 ライブラリを使用して、あるスケッチから別のスケッチに 2 つの変数を送信しようとしています。送信するメッセージは次のように作成されます。

 OscMessage myMessage = new OscMessage("/test");
 myMessage.add(title);
 myMessage.add("Zeit");
 oscP5.send(myMessage, remoteLocation);

2 番目のスケッチでは、次のようなデータを受け取ります。

 void oscEvent(OscMessage theOscMessage) {
   if(theOscMessage.checkAddrPattern("/test")) {
     String title = theOscMessage.get(0).stringValue();
     String layoutType = theOscMessage.get(1).stringValue();

     addToQueue(title, layoutType);
   }
 }

そして、ここで私の単純化された addToQueue 関数:

 void addToQueue(String title, String layoutType) {
   if(!existsInQueues(title)) {
     upcomingHeadlines.add(new Headline(title, printAxis, scrollSpeed, layoutType));
   } 
 }

スケッチを開始するたびに、次のエラーが表示されます。

エラー @ OscP5 エラー。OscMessage をプログラムのメソッドに転送中にエラーが発生しました。着信 OscMessages が解析されるメソッドで発生する可能性のあるエラーがないかコードをチェックしてください。担当メソッド:oscEvent java.lang.reflect.InvocationTargetException

layoutType-Variableまで問題を追跡することができました。私が変われば

  String layoutType = theOscMessage.get(1).stringValue();

  String layoutType = "Zeit";

エラーは発生しません。どちらのバージョンも同じ結果になるはずなので、これは非常に紛らわしいです。エラーメッセージは何の役にも立ちません。


編集

そのような2つの可能な変数を比較しました:

String layoutType = theOscMessage.get(1).stringValue();
String layoutTypeB = "Zeit";
if(layoutType.equals(layoutTypeB)) println("Same String!");

コンソールに出力されるので、両方とも同じでなければなりません…もうどこでエラーを検索すればよいかわかりません。


編集 2

2 番目のスケッチを次のtry {...} catch(Exception ex) {ex.printStackTrace();}ようにラップしました。

void oscEvent(OscMessage theOscMessage) {
  try {  
    if(theOscMessage.checkAddrPattern("/test")) {
      if(debug && debugFeed) println("Received message from other sketch.");

      String title = theOscMessage.get(0).stringValue();
      String layoutTypeO = (String)theOscMessage.get(1).stringValue();
      String layoutType = "Zeit";
      if(debug && debugTemp) {
        if(layoutType.equals(layoutTypeO)) println("IS DOCH GLEICH!");
      }
      if(debug && debugFeed) println("Parsed Information.");
      if(debug && debugFeed) println("-----");
      addToQueue(title, layoutTypeO);
    }
  } catch(Exception ex) {ex.printStackTrace();}
}

その結果、次のエラーが表示されます。

java.lang.IndexOutOfBoundsException: Index: 0, Size: 0  
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)  
    at java.util.ArrayList.get(ArrayList.java:411)  
    at printer$Headline.useLayout(printer.java:260)  
    at printer$Headline.<init>(printer.java:188)  
    at printer.addToQueue(printer.java:407)  
    at printer.oscEvent(printer.java:395)  
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)  
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
    at java.lang.reflect.Method.invoke(Method.java:606)  
    at oscP5.OscP5.invoke(Unknown Source)  
    at oscP5.OscP5.callMethod(Unknown Source)  
    at oscP5.OscP5.process(Unknown Source)  
    at oscP5.OscNetManager.process(Unknown Source)  
    at netP5.AbstractUdpServer.run(Unknown Source)  
    at java.lang.Thread.run(Thread.java:744)

編集 4

私のHeadline-Class のコンストラクタ:

class Headline {

  //Define Variables
  Layout layout;
  String title, lastHeadline;
  float yPos, speed;
  float transparency = 255;
  boolean fullyPrinted = false;
  int boundingBoxHeight;

  // Initialize Class Function
  Headline(String t, float y, float s, String lay) {
    title = t;
    yPos = y;
    speed = s;
    layout = useLayout(lay);
    boundingBoxHeight = calculateTextHeight(title);
  }

あなたも知りたいかもしれないuseLayout()ので、ここにあります:

Layout useLayout(String name) {
    ArrayList layoutVariants = new ArrayList<Layout>();
    int existingLayouts = layouts.size();
    Layout chosenLayout;

    for(int i = 0; i < existingLayouts; i++) {
      Layout currentLayout = (Layout)layouts.get(i);
      if(currentLayout.layoutType == name) {
        layoutVariants.add(currentLayout);
      }
    }

    if(layoutVariants != null) {
      int rand = (int)(Math.random() * layoutVariants.size());
      chosenLayout = (Layout)layoutVariants.get(rand);
    } else {
      chosenLayout = (Layout)layouts.get((int)(Math.random() * existingLayouts)); 
    }
  return chosenLayout;
}
4

1 に答える 1

3

コードには 2 つの問題があり、その両方がuseLayoutメソッドにあります。

Strings最初の問題は、次の行で s を正しく比較していないことです。

    if(currentLayout.layoutType == name) {

nameでありString、私もそうだと思いcurrentLayout.layoutTypeます。String等しいが同じではない2 つの は、 の下では等しいとは言えません==。この結果、layoutVariantsリストはおそらくforループの最後で空になります。

この行は次のようになります。

    if(currentLayout.layoutType.equals(name)) {

この質問も参照してください

layoutVariants2 つ目の問題は、リストが空の場合を正しく処理できないことです。問題は次の行にあります。

    if(layoutVariants != null) {

layoutVariantsnull になることはないため、このステートメントのelse分岐は決して実行されません。ゼロになるifので、常にゼロになります。空の ArrayList でインデックス 0 の要素を取得しようとすると、表示されているものを正確に取得できます。layoutVariants.size()randIndexOutOfBoundsException

else指定されたレイアウト名が認識されない場合、つまり、layoutVariantsリストがnull ではなくemptyの場合、ブロックを実行する必要があると思います。その場合、この行を次のように変更します

    if(!layoutVariants.isEmpty()) {

!の前の (演算子ではない) に注意してくださいlayoutVariants。要素が空でないif場合は、ステートメントの下のコードを実行する必要があります。layoutVariants

あなたのコメントに応じて編集nullしてください: ArrayList は空のものとほとんど同じではありません。 null変数が特定の型のオブジェクトを持たないことを意味する特別な値です。

実世界の類推を試してみましょう: ショッピング バッグです。バッグが空の場合、またはバッグがまったくない場合は、いずれにしても買い物はありません。ただし、空のバッグに物を入れて、その中に何個入っているかなどを数えることはできます。バッグを持っていない場合、アイテムを入れるバッグがないため、アイテムを入れても意味がありません。 nullバッグを持っていない場合を表します。

同様に、 aStringは文字のコレクションであり、文字のコレクションは文字が含まれていなくても存在できます。

isEmpty()任意のコレクションに使用できます。また、Java 6 以降を使用している場合は、文字列にも使用できます。頭のてっぺんから、isEmptyメソッドを持つ他のクラスに名前を付けることはできません。これらのクラスのドキュメントを参照して確認する必要があります。

私は Processing をあまり扱ったことがありませんが、Processing が Java 上に構築されていることは知っているので、標準の Java メソッドはどれも機能すると思います。また、変数の「クリア」について心配する必要はありません。JVM は一般に、後でクリアするのが得意です。この点で、あなたのコードに間違いはありません。

あなたのさらなるコメントに応じてEDIT 2ArrayList arr; : type の変数を宣言しますArrayList。ただし、変数arr初期化されていません: 値がなく ( もありませんnull)、値を割り当てる前にこの変数の値を読み取ろうとするとエラーになります。

ArrayList arr;
System.out.println(arr);     // compiler error: arr might not have been initialised.

代入nullすると、コードがコンパイルされます。

ArrayList arr = null;
System.out.println(arr);     // prints 'null'.

if変数を宣言して名前を付ける必要はあまりありませんが、一般的なケースの 1 つは、ステートメントの両側で同じ変数に異なる値を割り当てたい場合です。次のコードはコンパイルされません。

int y = getMeSomeInteger();   // assume this function exists
if (y == 4) {
    int x = 2;
} else {
    int x = 5;
}
System.out.println(x);        // compiler error: cannot find symbol x

コンパイルされない理由は、各変数xが中括弧内でのみ使用可能であり、{それ}を含むためです。下部では、どちらの変数xも使用できないため、コンパイラ エラーが発生します。

xさらに上に宣言する必要があります。代わりに次のように書くこともできます。

int y = getMeSomeInteger();   // assume this function exists
int x = 0;
if (y == 4) {
    x = 2;
} else {
    x = 5;
}
System.out.println(x);

このコードはコンパイルおよび実行されますが、0最初に割り当てられた値は使用されxません。これを行う意味はあまりありません。変数を宣言することで、この未使用の値を取り除くことができますが、すぐに値を与えることはありません。

int y = getMeSomeInteger();   // assume this function exists
int x;
if (y == 4) {
    x = 2;
} else {
    x = 5;
}
System.out.println(x);
于 2014-01-24T20:49:45.023 に答える