在网格窗格中移动标记

时间:2016-07-13 12:16:44

标签: javafx grid

我创建了一个包含多行的网格窗格。标记应该只能在1行上移动。移动鼠标时,它应仅向左,向右或向右移动。当您单击标记时,它应该被锁定,不再移动。它应该用不同的颜色突出显示。 我怎么能得到这个? 如果您知道任何教程或示例,请添加,谢谢。

消息输出:

  

执行   C:\ Users \用户s22380 \桌面\ TEMP \ JavaFXApplication9 \ DIST \ run269988000 \ JavaFXApplication9.jar   使用平台C:\ Program Files \ Java \ jdk1.8.0_92 \ jre / bin / java   Application构造函数中的异常   java.lang.reflect.InvocationTargetException at   sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:498)at   com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)     在   com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:498)at   sun.launcher.LauncherHelper $ FXHelper.main(LauncherHelper.java:767)   引起:java.lang.RuntimeException:无法构造Application   实例:类javafxapplication9.JavaFXApplication9 at   com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)     在   com.sun.javafx.application.LauncherImpl.lambda $ launchApplication $ 155(LauncherImpl.java:182)     在java.lang.Thread.run(Thread.java:745)引起:   java.lang.reflect.InvocationTargetException at   sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)     在   sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)     在   sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)     at java.lang.reflect.Constructor.newInstance(Constructor.java:423)     在   com.sun.javafx.application.LauncherImpl.lambda $ launchApplication1 $ 161(LauncherImpl.java:819)     在   com.sun.javafx.application.PlatformImpl.lambda $ runAndWait $ 175(PlatformImpl.java:326)     在   com.sun.javafx.application.PlatformImpl.lambda为$ null $ 173(PlatformImpl.java:295)     在java.security.AccessController.doPrivileged(Native Method)at   com.sun.javafx.application.PlatformImpl.lambda $ runLater $ 174(PlatformImpl.java:294)     在   com.sun.glass.ui.InvokeLaterDispatcher $ Future.run(InvokeLaterDispatcher.java:95)     at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)at   com.sun.glass.ui.win.WinApplication.lambda为$ null $ 148(WinApplication.java:191)     ... 1更多引起:java.lang.NullPointerException at   sample.Controller。(Controller.java:33)at   javafxapplication9.JavaFXApplication9。(JavaFXApplication9.java:19)     ... 13更多异常运行应用程序   javafxapplication9.JavaFXApplication9 Java结果:1正在删除   目录   C:\ Users \用户s22380 \桌面\ TEMP \ JavaFXApplication9 \ DIST \ run269988000   jfxsa-run:BUILD SUCCESSFUL(总时间:1秒)

1 个答案:

答案 0 :(得分: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项目时,这基本上就是示例代码。我将其更改为显式设置控制器。但这只是个人偏好。

xaml     

<?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>

再次。基本上是默认的东西。

我还添加了一个样式表来定义不可移动状态的不同锁。 redStyle.css

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

现在为控制器。

它会做一些事情:

  • 收听我想要推送的对象的鼠标事件。如果delata足够大我会移动它=&gt;如果鼠标移动得足够快
  • 按下按钮后,我会关闭样式表以获得不同的外观。现在这种风格适用于场景中的所有按钮。它可以更改为仅适用于特定的一个。

       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;
                        }
                    }
                });
            }
        }
    }