0

最初に、これについて提供できる可能性のあるガイダンスに感謝します。私はこれを機能させるために頭を悩ませており、ここで多くのスレッドを見てきましたが、運がありません. 私は Java と JavaFX は初めてですが、主に MSFT Visual Studio で C# のバックグラウンドを持っています。現在、IDE プラットフォームとして IntelliJ を使用しています。

私がやろうとしていることは (私が考えた) 十分に単純です: 私は、センサーを読み取っている Arduino コントローラーからのデータを読み取り、正常に解析しています。データはコンマ区切り形式であり、バッファリングされたリーダーとシリアルポートイベントを使用して、行を解析し、string.split してから (Double に変換した後) 配列に配置できます。この部分はうまく機能し、コードからわかるように、これも問題なくコンソールに出力しています。

package sample;

import eu.hansolo.enzo.gauge.RectangularGauge;
import gnu.io.*;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.fxml.FXML;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.io.*;

public class Main extends Application implements SerialPortEventListener {
SerialPort serialPort = null;
private BufferedReader serialIn;
private OutputStream serialOut;
public Double power;


@FXML
private RectangularGauge fwdpower;


@Override
public void start(Stage primaryStage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
    primaryStage.setTitle("Power Meter");
    primaryStage.setScene(new Scene(root, 380, 320));
    primaryStage.show();

    //
    CommPortIdentifier port = CommPortIdentifier.getPortIdentifier("COM60");
    CommPort commPort = port.open(this.getClass().getName(), 2000);
    serialPort = (SerialPort) commPort;
    serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
    serialIn = new BufferedReader(new InputStreamReader((serialPort.getInputStream())));
    serialPort.addEventListener(this);
    serialPort.notifyOnDataAvailable(true);
    //
}


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

@Override
public void serialEvent(SerialPortEvent e) {
    try {
        String line = serialIn.readLine();
        String[] Values = line.split(",");
        power = Double.parseDouble(Values[1]);
        System.out.println(power / 5);
        }  //This works as expected and shows values on console
        fwdpower.setValue(power/5); //Shows NOTHING! UGHHHH!
    catch (IOException ex) {ex.printStackTrace();
    }
}

今、難しい部分:私は完全にイライラしています!!

jfxtras ゲージからゲージを駆動しようとしています。適切なライブラリをすべてインポートし、シーンビルダーで非常にシンプルな GUI を作成しました。作成された XML ファイルは次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>

<?import eu.hansolo.enzo.gauge.RectangularGauge?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>


<GridPane alignment="center" hgap="10" vgap="10"        xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65"            fx:controller="sample.Controller">
 <columnConstraints>
  <ColumnConstraints />
 </columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
  <Pane prefHeight="342.0" prefWidth="377.0">
     <children>
        <RectangularGauge fx:id="fwdpower" layoutX="25.0" layoutY="22.0"                         minValue="1.0" />    
     </children>
  </Pane>
  </children>
  </GridPane>

そして、これがコントローラです:(ボタンやそのようなものを持ちたくないので、現時点では何も入っていません...データを表示するだけです:

package sample;

import eu.hansolo.enzo.gauge.RectangularGauge;
import gnu.io.SerialPortEvent;
import javafx.fxml.FXML;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Controller {

 }

さまざまな組み合わせを試しましたが、ゲージは serialPort から読み取ったデータを表示することを拒否します。これは、GUI がメインとは別のスレッドにあることに関係している可能性があると思います (検索して読んでいます) が、私の人生では、この一見単純なタスクを機能させるためにコードを変更する方法がわかりません。私が望むのは、ゲージがデータを表示することだけです....私は完全に愚かなことをしているかもしれないことを知っています....しかし、これを理解することはできません.

どうすればこれを達成できるかについてのアイデアはありますか?

PS:コントローラーでイベントハンドラーを作成すると、たとえばボタンを使用して、ボタンを押したときにゲージを任意の値で移動させることができます。シリアルイベントが発生したときに同じことができないのはなぜですか????

助けてください!!!!

4

1 に答える 1

0

@FXML-注釈付きフィールドは、によって作成されたコントローラーでのみ初期化されFXMLLoaderます。任意のオブジェクトのフィールドに単純に注釈を付けて、ローダーによって初期化されることを期待することはできません。

コントローラーで注釈付きフィールドを作成し、それを設定するメソッドを定義します。

package sample;

import eu.hansolo.enzo.gauge.RectangularGauge;
import gnu.io.SerialPortEvent;
import javafx.fxml.FXML;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Controller {

    @FXML
    private RectangularGauge fwdpower ;

    public void setFwdPower(double power) {
        fwdpower.setValue(power);
    }
}

次に、コントローラーへの参照を取得し、その上でメソッドを呼び出します。serialEventメソッドはバックグラウンド スレッドから呼び出されるため、コントローラーへの呼び出しを次のようにラップする必要があることに注意してくださいPlatform.runLater(...)

package sample;

import eu.hansolo.enzo.gauge.RectangularGauge;
import gnu.io.*;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.fxml.FXML;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;

import java.io.*;

public class Main extends Application implements SerialPortEventListener {

    SerialPort serialPort = null;
    private BufferedReader serialIn;
    private OutputStream serialOut;


    private Controller controller ;    

    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        Parent root = loader.load();

        controller = loader.getController();

        primaryStage.setTitle("Power Meter");
        primaryStage.setScene(new Scene(root, 380, 320));
        primaryStage.show();

        //
        CommPortIdentifier port = CommPortIdentifier.getPortIdentifier("COM60");
        CommPort commPort = port.open(this.getClass().getName(), 2000);
        serialPort = (SerialPort) commPort;
        serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
        serialIn = new BufferedReader(new InputStreamReader((serialPort.getInputStream())));
        serialPort.addEventListener(this);
        serialPort.notifyOnDataAvailable(true);
        //
    }


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

    @Override
    public void serialEvent(SerialPortEvent e) {
        try {
            String line = serialIn.readLine();
            String[] values = line.split(",");
            final double power = Double.parseDouble(values[1]);
            System.out.println(power / 5);
            Platform.runLater(() -> controller.setFwdpower(power/5));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

}
于 2016-04-11T23:44:38.917 に答える