2016-07-13 11 views
-1

グリッドペインをいくつか作成しました。マーカーは1行でのみ移動可能です。マウスを動かすときには、左右にだけ動かすべきです。マーカーをクリックすると、それはロックされ、動かなくなります。別の色で強調表示する必要があります。 どうすればこの問題を解決できますか? チュートリアルや例が分かっていれば、ありがとうございます。グリッドペインでの移動マーカー

メッセージ出力:

C実行:\ユーザー\ s22380 \デスクトップ\ tempに\ JavaFXApplication9 \ distの\ run269988000 \ JavaFXApplication9.jar 使用してプラットフォームのC:\プログラムファイル\のJava \ jdk1.8.0_92 \ sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)でアプリケーションのコンストラクタ sun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブメソッド)で にjava.lang.reflect.InvocationTargetExceptionのjre/binに/ javaの 例外 で sun.reflect.DelegatingMethodAccessorI mpl.invoke(DelegatingMethodAccessorImpl.java:43) com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389) ATでjava.lang.reflect.Method.invoke(Method.java:498)で com.sun.javafx.application.LauncherImpl.launchApplication sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)でsun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブメソッド)で(LauncherImpl.java:328) で sun.launcher.LauncherHelper $ FXHelper.main(LauncherHelper.java:767でjava.lang.reflect.Method.invokeで sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) (Method.java:498) ) 原因:java.lang.RuntimeException:アプリケーション インスタンスを作成できません: com.sun.javafx.application.LauncherImplでcom.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907) におけるクラスjavafxapplication9.JavaFXApplication9 .lambda $ launchApplication $ 155(LauncherImpl.java:182) at java.lang.Thread.run(Thread.java:745)原因: でjava.lang.reflect.InvocationTargetExceptionが発生しました。sun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブ における方法) でsun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructor AccessorImpl.java:45) com.sun.javafx.application.LauncherImpl.lambda $ launchApplication1 $ 161でjava.lang.reflect.Constructor.newInstance(Constructor.java:423) で (LauncherImpl.java:819) でjavaので com.sun.javafx.application.PlatformImpl.lambda $ nullに$ 173で com.sun.javafx.application.PlatformImpl.lambda $ runAndWait $ 175(PlatformImpl.java:326) (PlatformImpl.java:295) 。 com.sun.glass.ui.InvokeLaterDispatcher $ Future.runで com.sun.javafx.application.PlatformImpl.lambda $ runLater $ 174において(ネイティブメソッド)(PlatformImpl.java:294) (InvokeLaterDispatcher security.AccessController.doPrivileged .java:95) at com.sun.glass.ui.wi n.WinApplication._runLoop(ネイティブメソッド)at com.sun.glass.ui.win.WinApplication.lambda $ null $ 148(WinApplication.java:191) ... 1他の原因:java.lang.NullPointerException sample.Controller。(Controller.java:33)at javafxapplication9.JavaFXApplication9。(JavaFXApplication9.java:19) ...13以上の例外実行中のアプリケーション javafxapplication9.JavaFXApplication9のJava結果:1 ディレクトリを削除する C:\ Users \ユーザーs22380 \デスクトップ\ tempに\ JavaFXApplication9 \ distの\ run269988000 jfxsa・ラン:ビルドが成功(合計時間:1秒)

これについて

答えて

0

方法:Main.java

package sample; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Main extends Application 
{ 
    Controller controller = new Controller(10,10); 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml")); 
     loader.setController(this.controller); 
     Parent root = (Parent)loader.load(); 
     this.controller.InitUi(); 
     primaryStage.setTitle("Hello World"); 
     primaryStage.setScene(new Scene(root, 300, 275)); 
     primaryStage.show(); 
    } 

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

あなたはIntelliJの中に新しいJavaFXのプロジェクトを言うとき、これは基本的にサンプルコードです。コントローラを明示的に設定するように変更しました。しかしそれは単に個人的な好みです。

再びその

<?import javafx.scene.layout.*?> 

<GridPane fx:id="mainGrid" alignment="center" gridLinesVisible="true" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"> 
    <children> 
    </children> 
</GridPane> 

ためのXAML。基本的にはデフォルトのものです。

また、私は、可動でない状態のために異なるロックを定義するスタイルシートを追加しました。 redStyle.cssコントローラの今

.button { 
    -fx-text-fill: #006464; 
    -fx-background-color: #DFB951; 
    -fx-border-radius: 20; 
    -fx-background-radius: 20; 
    -fx-padding: 5; 
} 

。それはいくつかのことを行います

  • は、私の周りにプッシュしたいオブジェクトのマウスイベントに耳を傾けます。デリータが十分大きければ、私はそれを移動させます=>マウスが十分速く動いた場合
  • ボタンを押すと、スタイルシートが切り替わります。現在、このスタイルはシーンのすべてのボタンで機能します。それは、特定のものに対してのみ働くように変更することができます。

    package sample; 
    
    
    import javafx.event.ActionEvent; 
    import javafx.event.EventHandler; 
    import javafx.fxml.FXML; 
    
    import javafx.scene.control.Button; 
    import javafx.scene.input.MouseEvent; 
    import javafx.scene.layout.ColumnConstraints; 
    import javafx.scene.layout.GridPane; 
    import javafx.scene.layout.RowConstraints; 
    import javafx.scene.shape.Rectangle; 
    
    public class Controller 
    { 
        @FXML 
        private GridPane mainGrid; 
    
        @FXML 
        private Button movable; 
    
        private final int sizeX; 
        private final int sizeY; 
    
        private final double minMoveDistanc = 3; 
    
        private boolean canMove = true; 
    
        private Double lastX = null; 
        private Double lastY = null; 
    
        private String redButtonStyle = Controller.class.getResource("redStyle.css").toExternalForm(); 
    
        public Controller(int sizeX, int sizeY) 
        { 
         this.sizeX = sizeX; 
         this.sizeY = sizeY; 
        } 
    
        public void InitUi() 
        { 
         if (this.mainGrid != null) 
         { 
          final int numCols = sizeX; 
          final int numRows = sizeY; 
          for (int i = 0; i < numCols; i++) 
          { 
           ColumnConstraints colConst = new ColumnConstraints(); 
           this.mainGrid.getColumnConstraints().add(colConst); 
          } 
          for (int i = 0; i < numRows; i++) 
          { 
           RowConstraints rowConst = new RowConstraints(); 
           this.mainGrid.getRowConstraints().add(rowConst); 
          } 
    
          // add rectangle to keep grid in size 
          for (int i = 0; i < numCols; i++) 
          { 
           for (int j = 0; j < numRows; j++) 
           { 
            Rectangle rect = new Rectangle(); 
            rect.setWidth(50); 
            rect.setHeight(50); 
            this.mainGrid.add(rect,i,j); 
           } 
          } 
    
          // ad movable object (Button) 
          this.movable = new Button("Hallo"); 
          this.movable.setPrefWidth(50); 
          this.movable.setPrefHeight(50); 
          this.movable.setOnAction(new EventHandler<ActionEvent>() 
          { 
           @Override 
           public void handle(ActionEvent actionEvent) 
           { 
            canMove = ! canMove; 
            movable.setText(canMove? "move" : "stop"); 
            if (canMove) 
            { 
             movable.getScene().getStylesheets().remove(redButtonStyle); 
            } 
            else 
            { 
             movable.getScene().getStylesheets().add(redButtonStyle); 
            } 
           } 
          }); 
          this.mainGrid.add(this.movable,5,5); 
    
         } 
    
         if (this.movable != null) 
         { 
          this.movable.setOnMouseEntered(new EventHandler<MouseEvent>() 
          { 
           @Override 
           public void handle(MouseEvent mouseEvent) 
           { 
            lastX = null; 
            lastY = null; 
           } 
          }); 
    
          this.movable.setOnMouseExited(new EventHandler<MouseEvent>() 
          { 
           @Override 
           public void handle(MouseEvent mouseEvent) 
           { 
            lastX = null; 
            lastY = null; 
           } 
          }); 
    
          this.movable.setOnMouseMoved(new EventHandler<MouseEvent>() 
          { 
           @Override 
           public void handle(MouseEvent mouseEvent) 
           { 
            if (!canMove) 
            { return; } 
    
            double x = mouseEvent.getSceneX(); 
            double y = mouseEvent.getSceneY(); 
    
            if (lastX == null) 
            { 
             lastX = x; 
             lastY = y; 
             return; 
            } 
    
            // calculate delta 
            double deltaX = x - lastX; 
            double deltaY = y - lastY; 
    
            // remember new position 
            lastX = x; 
            lastY = y; 
    
            boolean moved = false; 
    
            // x movement 
            if (Math.abs(deltaX) > minMoveDistanc) 
            { 
             moved = true; 
             int currentColumn = GridPane.getColumnIndex(movable); 
    
             if (deltaX < 0) 
             { 
              GridPane.setColumnIndex(movable, Math.max(currentColumn -1 ,0)); 
             } 
             else 
             { 
              GridPane.setColumnIndex(movable, Math.min(currentColumn + 1 ,sizeX-1)); 
             } 
            } 
    
            // y movement 
            if (Math.abs(deltaY) > minMoveDistanc) 
            { 
             moved = true; 
             int currentRow = GridPane.getRowIndex(movable); 
    
             if (deltaY < 0) 
             { 
              GridPane.setRowIndex(movable, Math.max(currentRow - 1 ,0)); 
             } 
             else 
             { 
              GridPane.setRowIndex(movable, Math.min(currentRow + 1 ,sizeY-1)); 
             } 
            } 
    
            if (moved) 
            { 
             lastX = null; 
             lastY = null; 
            } 
           } 
          }); 
         } 
        } 
    } 
    
+0

あなたの努力に感謝し、完璧に提示された例。私はそれを試みたが、実行時に例外が発生する。なぜそれほど正確ではないか。私はcssファイルを含んでいません。どこに置くべきですか? – user2909180

+0

他のファイルの隣に 'String redButtonStyle = Controller.class.getResource(" redStyle.css ")。toExternalForm();を置くだけで、同じフォルダからロードしようとします。また、あなたの例外は何ですか? – FrankT

+0

'原因:sample.Controller(Controller.java:33)の' controller 33行でのjava.lang.NullPointerExceptionは、ファイルからのスタイルの読み込みです。それはpropably見つけることができません。スタイルのものを削除して、残りが機能するかどうかを確認してください。 – FrankT

関連する問題