2017-10-31 7 views
1

考え方はMOUSE_CLICKEDにボールを描くことです そして、その中心から始まる行をMOUSE_DRAGGEDハンドラで解放するまで描きます。 しかしそれは反対に完了し、私は単にそれを得ることはありません - それは最初の行を描画し、マウスをリリースした後、ボールが表示されます。 誰に問題がどこにあるのか分かりませんか?ここでJavaFX。ボールを描いてその中心から線を引く

public class Step extends Application { 

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

    @Override 
    public void start(Stage stage) { 
     Canvas layer1 = new Canvas(500, 500); 
     Group root = new Group(); 
     root.getChildren().add(layer1); 

     Ball c_ball = new Ball(0, 0, 50, 0, 0); 
     Arrow arrow = new Arrow(0, 0, 0, 0); 

     layer1.addEventHandler(MouseEvent.MOUSE_CLICKED, 
       ev -> { 
        c_ball.x = ev.getX(); 
        c_ball.y = ev.getY(); 
        arrow.start_x = ev.getX(); 
        arrow.start_y = ev.getY(); 
        GraphicsContext gc = layer1.getGraphicsContext2D(); 
        gc.setFill(Color.DARKCYAN); 
        gc.fillOval(c_ball.x - c_ball.size/2, c_ball.y - c_ball.size/2, c_ball.size, c_ball.size); 
       }); 

     layer1.addEventHandler(MouseEvent.MOUSE_DRAGGED, 
       ev -> { 
        GraphicsContext gc_arr = layer1.getGraphicsContext2D(); 
        gc_arr.clearRect(0, 0, layer1.getWidth(), layer1.getHeight()); 
        gc_arr.strokeLine(arrow.start_x, arrow.start_y, ev.getX(), ev.getY()); 
       }); 

     Scene scene = new Scene(root, 500, 500); 
     stage.setScene(scene); 
     stage.show(); 

    } 
} 

は、クラスのボールです:

public class Ball { 
public double x, y; 
public double dx, dy; 
public double size; 


public Ball(double x, double y, double size, double dx, double dy) { 
    this.x = x; 
    this.y = y; 
    this.size = size; 
    this.dx = dx; 
    this.dy = dy; 

}} 

そして、あなたが表示されますMouseEvent.MOUSE_CLICKEDのドキュメントを見てみると

public class Arrow { 
public double start_x, start_y; 
public double end_x, end_y; 

public Arrow(double x1, double y1, double x2, double y2) { 
    this.start_x = x1; 
    this.start_y = y1; 
    this.end_x = x2; 
    this.end_y = y2; 
}} 
+0

「ボール」クラスと「アロー」クラスを提供できますか? – aKilleR

+1

@aKilleRは説明にそれらを追加しました – Diana

+0

私はこの正確な問題を解決することができましたが、複数の行が必要な場合は動作しません。あなたが望むなら、答えとしてコードを掲示することができます。これは次のようになります:https://imgur.com/a/vkwBW。最初のボールラインのペアを描画した後、 'clearRect'のために別のラインを描画しようとします – Sunflame

答えて

3

矢印:

イベントタイプjavafx.scene.input .MouseEvent.MOUSE_CLICKED

このイベントは、マウスボタンがクリックされたとき(同じノードで が押されたとき)に発生します。このイベントは、任意のノードに対してボタンのような動作を提供します( )。長いドラッグでも、クリック イベントが発生する可能性があることに注意してください(マウスが の両方が押されていて、一番上のノードに配信されています)。

あなたが探しているマウスイベントはMouseEvent.MOUSE_PRESSEDですが、あなたのコードはどちらの場合でも動作しません。その理由は、gc_arr.clearRect(0, 0, layer1.getWidth(), layer1.getHeight());に電話すると、MOUSE_DRAGGEDイベント内のすべてをクリアすることになります。円を描画しますが、キャンバスをクリアして線を描画するだけです。その行を削除すると、マウスをドラッグするたびに複数の行が表示されますが、それは別の問題です。

私はキャンバスで自分のプログラムを実装する必要がありますか?

答えは、リスト(や配列などのようないくつかのデータ構造)の内部で維持する必要がありますYESすべてのコンポーネントである場合は、あなたがオブジェクトを更新し、すべて

を再描画する必要が何かを変更したいとき

答えがの場合正しいアプローチを取っているので、キャンバスをAnchorPaneまたはPaneなどに変更し、ノード(円、線など)をペインに直接追加する必要があります。

ここでは、Canvasの代わりにAnchorPaneを使用した簡単な例を示します。例では

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.AnchorPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.shape.Line; 
import javafx.stage.Stage; 

public class ShapesTest extends Application { 

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

    private double arrayStartX; 
    private double arrayStartY; 
    private AnchorPane root; 
    private Line l; 

    @Override 
    public void start(Stage stage) { 

     root = new AnchorPane(); 

     root.addEventHandler(MouseEvent.MOUSE_PRESSED, ev -> { 
      addBall(ev.getX(), ev.getY()); 
      arrayStartX = ev.getX(); 
      arrayStartY = ev.getY(); 

     }); 

     root.addEventHandler(MouseEvent.MOUSE_DRAGGED, ev -> { 
      if (l == null) { 
       addLine(ev.getX(), ev.getY()); 
      } else { 
       l.setEndX(ev.getX()); 
       l.setEndY(ev.getY()); 
      } 

     }); 

     root.addEventHandler(MouseEvent.MOUSE_RELEASED, ev -> { 
      l = null; 
     }); 

     Scene scene = new Scene(root, 500, 500); 
     stage.setScene(scene); 
     stage.show(); 

    } 

    private void addLine(double x, double y) { 
     l = new Line(arrayStartX, arrayStartY, x, y); 
     root.getChildren().add(l); 

    } 

    private void addBall(double x, double y) { 
     Circle c = new Circle(x, y, 15); 
     c.fillProperty().set(Color.DARKCYAN); 
     root.getChildren().add(c); 
    } 
} 

あなたは可能性が上記のあなたが好き、その後、マウスボタンを離したときに、各ボールに物理学を適用する場合は、独自のカスタムオブジェクト上のサークルと線の情報を保持します。

+0

OMg、ありがとう:)それは動作します!そう簡単.... – Diana

+1

あなたはおそらくあなたのアプローチで間違ったトラックにあります。 Canvasは、このようなインタラクティブな描画の正しいコンセプトではありません。なぜシーングラフを使用しなかったのですか? – mipa

+0

@JKostikiadis私はレイヤーとしてキャンバスを使用する必要がありますが、後でバックグラウンドでバウンスするボールがたくさんありますが、干渉することなく(バックグラウンドでのバウンスを止めて)上位レイヤの新しいレイヤーを描画する必要があります。 – Diana

関連する問題