質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.43%

  • Java

    14772questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • JavaFX

    429questions

    JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

JavaFXのエラー処理に関して

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 53

YM_anoahiro

score 8

前提・実現したいこと

現在、JavaFXでpingコマンドのデモを作成しようと考えています。
しかし、コンパイルも実行もできるのですが、時折以下のエラーメッセージが発生してしまいます。
お恥ずかしい話、どこからエラーが出ているかさっぱりな状態です。
どのようにエラー処理すればよいのか教えていただければと思います。

発生している問題・エラーメッセージ

「実行」のボタンを押すと時折このエラーが発生します。

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
        at javafx.graphics/com.sun.javafx.text.PrismTextLayout.addTextRun(PrismTextLayout.java:756)
        at javafx.graphics/com.sun.javafx.text.GlyphLayout.addTextRun(GlyphLayout.java:140)
        at javafx.graphics/com.sun.javafx.text.GlyphLayout.breakRuns(GlyphLayout.java:210)
        at javafx.graphics/com.sun.javafx.text.PrismTextLayout.buildRuns(PrismTextLayout.java:771)
        at javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1022)
        at javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:222)
        at javafx.graphics/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:245)
        at javafx.graphics/javafx.scene.text.Text.getLogicalBounds(Text.java:430)
        at javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1173)
        at javafx.graphics/javafx.scene.text.Text.access$300(Text.java:127)
        at javafx.graphics/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:148)
        at javafx.graphics/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90)
        at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)
        at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3831)
        at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3793)
        at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3741)
        at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3895)
        at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3687)
        at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1864)
        at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1656)
        at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1520)
        at javafx.graphics/javafx.scene.Parent.access$200(Parent.java:81)
        at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:117)
        at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:86)
        at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)
        at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3831)
        at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3793)
        at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3741)
        at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3895)
        at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3687)
        at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1864)
        at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1728)
        at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1667)
        at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1520)
        at javafx.graphics/javafx.scene.Parent.access$200(Parent.java:81)
        at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:117)
        at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:86)
~以下略~

該当のソースコード

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import java.util.*;

public class pp extends Application {
Label l1, l2,l3; // ラベル
Label[] lb = new Label[5];//ラジオボタン
    String[] lbin = {"     →自分のPCのIPアドレス(仮)","     →Yahoo!のサイト","     →コロンビアのサイト","     →ブラジルのサイト","     →存在しないIPアドレス"};
TextField tx1, tx2; // テキストフィールド
Button start,clear,kaisetu,ryouhou; // ボタン
TextArea textArea,ta2; // テキストエリア
RadioButton[] rb = new RadioButton[5];//ラジオボタン
    ToggleGroup ping;
    String[] cm = {"ping 10.40.83.63","ping www.yahoo.co.jp","ping www.columbia.edu","ping www.ibge.gov.br","ping 999.999.999.999"};
int num1, num2;

public void start(Stage stage) {
stage.setWidth(1200);
stage.setHeight(750);

////////////////////ラベル設定////////////////////
l1 = new Label("pingコマンドデモ");
l1.setFont(new Font(36));
//label1.setTextFill(Color.RED);色の設定
l2 = new Label("コマンド選択してください");
l3=new Label("          ");

for (int i = 0; i <lb.length ; i++) {
  lb[i] = new Label(lbin[i]);//ラベルの作成
}

////////////////////ラジオボタン設定////////////////////
ping=new ToggleGroup();
for (int i = 0; i <rb.length ; i++) {
  rb[i] = new RadioButton(cm[i]);//ラジオボタンの作成
  rb[i].setToggleGroup(ping);//ラジオボタンをpingグループに追加
  rb[i].setStyle("-fx-font-size: 18;");//フォント設定
}
rb[0].setSelected(true);
VBox rbAll = new VBox();

for(int i=0; i <rb.length ; i++){
  rbAll.getChildren().add(rb[i]);
  rbAll.getChildren().add(lb[i]);
}

//for (RadioButton r:rb) {//ラジオボタンをVBoxに入れる
    //rbAll.getChildren().add(r);  }

////////////////////ボタン設定////////////////////
start = new Button("実行結果表示");
start.setPrefSize(100,50);
start.setOnAction(event -> buttonStartPressed());
kaisetu = new Button("解説表示");
kaisetu.setPrefSize(100,50);
kaisetu.setOnAction(event -> buttonKaisetuPressed());
ryouhou = new Button("両方とも表示");
ryouhou.setPrefSize(205,50);
ryouhou.setOnAction(event -> buttonRyouhouPressed());
clear = new Button("Clear");
clear.setPrefSize(205,50);
clear.setOnAction(event -> buttonClearPressed());

////////////////////テキストエリア設定////////////////////
textArea = new TextArea("実行結果が表示されます。\nC:¥Users>");
textArea.setStyle("-fx-text-fill: white;-fx-font-size: 16;");
ta2=new TextArea("解説を表示します。");//22文字まで表示可能
ta2.setStyle("-fx-font-size: 14;");
//ta2.setPrefRowCount(10);// 行数を指定
ta2.setPrefColumnCount(20); // 列数を設定
ta2.setWrapText(true);

////////////////////配置設定////////////////////
HBox hbox = new HBox(5);
hbox.getChildren().addAll(start,kaisetu);

VBox vbox = new VBox(5);
vbox.setPadding(new Insets(20, 25, 25, 25));
vbox.getChildren().addAll(l1,l2,rbAll,l3,hbox,ryouhou,clear);

BorderPane root = new BorderPane();
root.setLeft(vbox);
root.setCenter(textArea);
root.setRight(ta2);

stage.setScene(new Scene(root));
stage.show();

textArea.lookup(".content").setStyle("-fx-background-color: black;");//色の変更
}

void buttonClearPressed(){
textArea.clear();
textArea.setText("実行結果が表示されます。\nC:¥Users>");
ta2.setText("解説が表示されます。");
}

void buttonStartPressed(){
if (rb[0].isSelected()){
    class Hyouzi  extends Thread{
      public void run(){
            textArea.appendText("ping 10.40.83.63\n10.40.83.63 に ping を送信しています 32 バイトのデータ:");
        for(int i=0;i<4;i++){
          textArea.appendText("\n10.40.83.63 からの応答: バイト数 =32 時間 <1ms TTL=128");
          try{
            Thread.sleep(1000);
          }catch(InterruptedException e){
            textArea.appendText("\n\nエラーが発生しました。\n\nC:¥Users>");
            return;
          }

      }
      textArea.appendText("\n\n10.40.83.63 の ping 統計:\n  パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)\n  ラウンド トリップの概算時間 (ミリ秒):\n  最小 = 0ms、最大 = 0ms、平均 = 0ms");
    textArea.appendText("\n\nC:¥Users>");
      }
    }
    Hyouzi t=new Hyouzi();
    t.start(); }
else if(rb[1].isSelected()){
  ~略~(if文の最初の内容とほぼ同じなので省略します。)
}
else if(rb[2].isSelected()){
  ~略~
}
else if(rb[3].isSelected()){
  ~略~
}
else{
 ~略~
}
}

void buttonKaisetuPressed(){
  if (rb[0].isSelected()){
    ta2.setText("自分のPC(仮)にping");
  }
  else if(rb[1].isSelected()){
    ta2.setText("yahoo!にping");
  }
  else if(rb[2].isSelected()){
    ta2.setText("コロンビアにping");
  }
  else if(rb[3].isSelected()){
    ta2.setText("ブラジルにping");
  }
  else{
    ta2.setText("偽ipアドレスにping");
  }
}

void buttonRyouhouPressed(){
  buttonKaisetuPressed();
  buttonStartPressed();
}

public static void main(String[] args) {
launch();
}
}

お願い

がちがちの初心者なのでoracleのサイトだけ載せていただいても理解するのが難しいためどのように書けばいいか教えて頂けると幸いです。
また、質問のマナー等が間違っている、内容がわかりにくい等ありましたらご指摘お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • swordone

    2019/01/11 02:58

    エラーの上が切れています。***Exceptionまたは***Errorを含み、かつCausedで始まらない行から載せてください。

    キャンセル

  • YM_anoahiro

    2019/01/11 03:07

    ご指摘ありがとうございます。
    編集したのですが、いかがでしょうか?

    キャンセル

回答 1

checkベストアンサー

0

再現させる方法

ご質問のコードの~略~という部分をコメントアウトしたソースで再現を試みましたがなかなか発生しません。ただ後述の問題が原因であると推測し再現確率を上げるべくHyouziクラスの定義を2か所(下記ソース参照)変えた上で「実行結果表示」ボタンを押すと似た現象が起きました。

class Hyouzi  extends Thread{
  public void run(){
    textArea.appendText("ping 10.40.83.63\n10.40.83.63 に ping を送信しています 32 バイトのデータ:");
    for (int i = 0; i < 100; i++) { //@@@ここ@@@
      textArea.appendText("\n10.40.83.63 からの応答: バイト数 =32 時間 <1ms TTL=128");
      try{
        Thread.sleep(1); //@@@ここ@@@
      }catch(InterruptedException e){
        textArea.appendText("\n\nエラーが発生しました。\n\nC:¥Users>");
        return;
      }
    }
    textArea.appendText("\n\n10.40.83.63 の ping 統計:\n  パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)\n  ラウンド トリップの概算時間 (ミリ秒):\n  最小 = 0ms、最大 = 0ms、平均 = 0ms");
    textArea.appendText("\n\nC:¥Users>");
  }
}

  

原因(推測)

以前の自分の回答
https://teratail.com/questions/167482#reply-249876
の対処方法(B)を中途半端に実装しておられることだと思います。どこが中途半端かというと

(B) 別のスレッドでsleepなどによる処理シーケンスを実装し、そのなかで画面の更新をPlatform.runLaterで要求する 

の赤字の部分の配慮がないことです。

はっきりわかりませんが、質問者さんの状況は

  • Threadとは何かが曖昧
  • Platform.runLaterが何故必要か不明だったのでとりあえず気にしないことにした

だったのではないかと推測します。「プログラムの並列動作」についての本質的な知識はJavaFX(あるいはswing)のようなGUIライブラリーを用いる際には必要な場面がありますので(少々難解かも知れませんが)曖昧なままにせず把握に努めることをお勧めします。

なお具体的コードについては元の質問に例を示してありますのでそれをよくご覧になってみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Java

    14772questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • JavaFX

    429questions

    JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。