《Java黑皮书基础篇第10版》 第15章【习题】

Java语言程序设计 习题第十五章

15.2章节习题

15.1 什么是事件源对象? 什么是事件对象? 描述事件源对象和事件对象之间的关系

事件源对象类似于一个JavaFX的节点,是一个可供操作的用户界面控件,如按钮、文本框、菜单等。

事件对象是从事件源产生的一个对象,用来执行一个命令,如单击按钮,输入文本框等。它包含了有关事件的相关信息,例如事件类型、事件源对象、事件发生的时间等。事件对象是一个具体的事件类的实例,每种类型的事件都有相应的事件类,例如ActionEventMouseEventKeyEvent等。

15.2 一个按钮可以触发一个MouseEvent事件吗? 一个按钮可以触发一个KeyEvent事件吗? 一个按钮可以触发一个 ActionEvent 事件吗?

Button是Node的子类,因此以上事件都可以触发

15.3章节习题

15.3 为什么一个处理器必须是一个恰当的处理器接口的实例?

处理器应该实现handle方法来处理一个事件,实现了接口,就强制实现了handle抽象方法

15.4 请说明如何注册一个处理器对象,以及如何实现一个处理器接口?

// 对于button来说,可以这样注册一个处理器对象
button.setOnAction(handler);
// 实现接口并覆写handle方法即可,例如
class EnlargeHandler implements EventHandler<ActionEvent> {
   
        @Override 
        public void handle(ActionEvent e) {
   
            circlePane.enlarge();
        }
}

15.5 EventHandler接口的处理器方法是什么?

handle方法

15.6 对一个按钮注册一个ActionEvent处理器的注册方法是什么?

button.setOnAction(handler)
15.4章节习题

15.7 一个内部类可以被除它所在的嵌套类之外的类所使用吗?

可以

15.8 修饰符 public、protected、private 以及 static 可以用于内部类吗?

可以

15.5章节习题

15.9 如果类A是类B中的一个内部类,A的类文件名字是什么? 如果类B包含两个匿名内部类A和C,这两个类的.class文件名是什么?

B$A.class

B$A.class, B$C.class

15.10 下面代码中的错误是什么?

public class Test extends Application {
   
  public void start(Stage stage) {
   
    Button btOK = new Button("OK");
    // 没有注册事件
  }

  private class Handler implements EventHandler<ActionEvent> {
   
    // 应该是ActionEvent,不是Action
    public void handle(Action e) {
   
      System.out.println(e.getSource());
    }
  }
}
public class Test extends Application {
   
  public void start(Stage stage) {
   
    Button btOK = new Button("OK");
		// 少了()
    btOK.setOnAction(new EventHandler<ActionEvent> {
   
      public void handle(ActionEvent e) {
   
        System.out.println(e.getSource());
      }
    // 少了);
    }  // Something missing here
  }
}
15.6章节习题

15.11 什么是 lambda 表达式? 使用 lambda 表达式进行事件处理的好处是什么? 一个 lambda 表达式的语法是什么?

编译器对待一个 lambda 表达式如同它是从一个匿名内部类创建的对象,可以简化代码

(type1 para1,, typen paramn) -> expression; 
(type1 para1,, typen paramn) -> {
   statements}; 
() -> expression;
() -> {
   statements}; 

15.12 什么是功能接口? 为什么对于一个 lambda 表达式而言,必须是一个功能接口?

只有一个抽象方法的接口

15.13 请给出以下代码的输出

package com.example.demo;

public class Test {
   
    public static void main(String[] args) {
   
        Test test = new Test();
        test.setAction1(() -> System.out.print("Action 1! "));
        test.setAction2(e -> System.out.print(e + " "));
        System.out.println(test.setAction3(e -> e * 2));
    }

    public void setAction1(T1 t) {
   
        t.m();
    }

    public void setAction2(T2 t) {
   
        t.m(4.5);
    }

    public double setAction3(T3 t) {
   
        return t.m(5.5);
    }
}

interface T1 {
   
    public void m();
}

interface T2 {
   
    public void m(Double d);
}

interface T3 {
   
    public double m(Double d);
}
Action 1! 4.5 11.0
15.8章节习题

15.14 对于一个鼠标事件而言,使用什么方法来得到鼠标点的位置?

e.getX()
e.getY()

15.15 对于一个鼠标按下、释放、单击、进入、退出、移动和拖动事件,使用什么方法来注册一个相应的处理器?

setOnMouseClicked(handler)
setOnMousePressed(handler)
setOnMouseReleased(handler)
setOnMouseEntered(handler)
setOnMouseExited(handler)
setOnMouseDragged(handler)
setOnMouseMoved(handler)
15.9章节习题

15.16 使用什么方法来针对键的按下、释放以及敲击事件注册处理器?这些方法定义在哪些类中?

// 这些方法定义在Node和Scene中
setOnKeyPressed(handler)
setOnKeyReleased(handler)
setOnKeyTyped(handler)

15.17 使用什么方法来从一个键的敲击事件中获得该键的字符?针对按下键和释放键的事件,使用什么方法来得到键的编码?

e.getCharacter()
e.getText()

15.18 如何设置一个节点获取焦点,从而它可以监听键盘事件?

// 实际上就是接收键盘输入
node.requestFocus();
15.10章节习题

15.19 如果在第29行和第33行将pane替换为scene或者primaryStage, 会出现什么情况

在本例中,scene和pane的尺寸大小是一样的,scene改变了,pane也会跟着改变

但是,stage的变化不会引起scene和pane的变化

15.11章节习题

15.20 如何将一个动画的循环次数设置为无限次?如何自动倒转一个动画?如何开始、暂停以及停止一个动画?

animation.setCycleCount(Timeline.INFINITY);
animation.setAutoReverse(true);
animation.start();
animation.pause();
animation.stop();

15.21 PathTransition, FadeTransition和Timeline是Animation的一个子类型吗?

是的

15.22 如何创建一个 PathTransition? 如何创建一个 FadeTransition? 如何创建一个 Timeline?

new操作符

15.23 如何创建一个关键帧?

new KeyFrame(Duration, handler)
15.12章节习题

15.24 程序是如何使球移动的?

每隔50毫秒,小球的圆心就会更换一次坐标

15.25 程序清单15-17中的代码是如何改变球的移动方向的?

通过改变dx的符号

15.26 当在弹球面板上按下鼠标时,程序将做什么?当在弹球面板上释放鼠标时,程序将做什么?

暂停和重启

15.27 在程序清单15-18中,如果第32行不存在,当你按下UP或者DOWN方向键的时候,会出现什么情况?

程序不会有反应

15.28 如果程序清单15-17中没有第23行,会出现什么情况?

程序只会执行一次,也就是50毫秒

编程练习题

*15.1 (选取4张卡牌)

请写一个程序,可以让用户通过单击Refresh按钮以显示从一副52张卡牌选取的4张卡牌,如图15-24a所示。(参见编程练习題14.3中关于如何获得4张随机卡牌中的提示)

package com.example.demo;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.ArrayList;

public class Test extends Application {
   
    private static final String PREFIX = "File:/Users/kevinwang/Downloads/Java语言程序设计/习题/JavaFX_Document/";
    private static final String SUFFIX = ".png";

    @Override
    public void start(Stage pStage) {
   
        // 52张牌太多了,找不到资源,因此功能简化一下,在5张牌里面随机选择3张
        // 用hBox储存随机的3张纸牌,用stackPane储存按钮,再把这两个面板一起放到BorderPane中
        // viewList储存全部5张纸牌,randomIndex储存3个随机整数,去决定哪3张图片被展示
        HBox hBox = new HBox();
        StackPane stackPane = new StackPane();
        BorderPane borderPane = new BorderPane();
        ArrayList<ImageView> viewList = new ArrayList<>();
        ArrayList<Integer> randomIndex = new ArrayList<>();

        // 创建纸牌
        for (int i = 0; i < 5; i++) {
   
            viewList.add(new ImageView(PREFIX + i + SUFFIX));
            viewList.get(i).fitWidthProperty().bind(hBox.widthProperty().multiply(0.33));
            viewList.get(i).setPreserveRatio(true);
        }

        // 创建按钮
        Button button = new Button("Refresh");

        // 添加图片到hBox
        addHBox(randomIndex, viewList, hBox);

        // 添加按钮到stackPane
        stackPane.getChildren().add(button);

        // 如果点击了按钮,就会清空hBox和randomIndex,重新执行一遍"添加图片到hBox"的过程
        button.setOnAction(e -> {
   
            hBox.getChildren().clear();
            randomIndex.clear();
            addHBox(randomIndex, viewList, hBox);
        });

        // 把按钮和纸牌图片添加到borderPane中
        borderPane.setCenter(hBox);
        borderPane.setBottom(stackPane);

        Scene scene = new Scene(borderPane, 200, 150);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }

    public void addHBox(ArrayList<Integer> randomIndex, ArrayList<ImageView> viewList, HBox hBox) {
   
        for (int i = 0; i < 3; i++) {
   
            int temp;
            // 下面的循环控制了randomIndex数组中不可以出现相同的元素。如果没有循环,直接创建随机数,会有如下效果
            // 随机数是3,4,5,那么程序正常允许;但是如果随机数是3,4,4,程序会报错,因为一个ImageView只能被写入一次面板,也就是一个子节点ImageView只能有一个父节点HBox
            do
                temp = (int) (Math.random() * 5);
            while (randomIndex.contains(temp));
            randomIndex.add(temp);
            hBox.getChildren().add(viewList.get(temp));
            hBox.setAlignment(Pos.CENTER);
        }
    }
}

输出结果:

在这里插入图片描述

15.2 (旋转一个四边形)

请写一个程序,在Rotate按钮被单击时,将一个四边形向右旋转15度,如图15-24b所示

package com.example.demo;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Test extends Application {
   
    // 初始化旋转角度
    double angle = 0;

    @Override
    public void start(Stage pStage) {
   
        StackPane stackPaneRectangle = new StackPane();
        StackPane stackPaneButton = new StackPane();
        BorderPane borderPane = new BorderPane();

        // 创建长方形并添加到面板
        Rectangle rectangle = new Rectangle(40, 10);
        rectangle.setFill(Color.TRANSPARENT);
        rectangle.setStroke(Color.BLACK);
        stackPaneRectangle.getChildren().add(rectangle);
        // 创建按钮并添加到面板
        Button button = new Button("Rotate");
        stackPaneButton.getChildren().add(button);

        // 如果点击了按钮,就会旋转
        button.setOnAction(e -> {
   
            rotate(rectangle);
        });

        // 把Nodes添加到borderPane中
        borderPane.setCenter(stackPaneRectangle);
        borderPane.setBottom(stackPaneButton);

        Scene scene = new Scene(borderPane, 100, 100);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }

    public void rotate(Rectangle  rectangle) {
   
        // 小球旋转的角度应该是累加的
        angle += 15;
        rectangle.setRotate(angle);
    }
}

输出结果:

在这里插入图片描述

*15.3 (移动小球)

编写一个程序,在面板上移动小球。应该定义一个面板类来显示小球,并提供向左、 向右 、向上和向下移动小球的方法,如图15-24c所示。请进行边界检査以防止球完全移到视线之外

package com.example.demo;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Test extends Application {
   
    @Override
    public void start(Stage pStage) {
   
        // pane用来储存圆圈,hBox用来储存按钮,text警告会在即将越界时发生,以上三个Node都会被放置在borderPane中
        Pane pane = new Pane();
        HBox hBox = new HBox();
        Text text = new Text("Next movement will be out of bound!");
        text.setFill(Color.RED);
        BorderPane borderPane = new BorderPane();

        // 创建圆形并添加到面板
        Circle circle = new Circle(100, 50, 15);
        circle.setStroke(Color.BLACK);
        circle.setFill(Color.TRANSPARENT);
        pane.getChildren().add(circle);
        // 创建按钮并添加到面板
        Button left = new Button("Left");
        Button right = new Button("Right");
        Button up = new Button("Up");
        Button down = new Button("Down");
        hBox.getChildren().addAll(left, right, up, down);
        hBox.setAlignment(Pos.CENTER);

        // 如果点击了按钮,就会移动,如果移动即将越界,会在顶部弹出警告
        left.setOnAction(e -> {
   
            // 清除可能存在的警告消息
            borderPane.setTop(null);
            if (circle.getCenterX() - circle.getRadius() * 2 < 0) {
   
                // 弹出警告并退出方法
                borderPane.setTop(text);
                return;
            }
            circle.setCenterX(circle.getCenterX() - circle.getRadius());
        });

        right.setOnAction(e -> {
   
            borderPane.setTop(null);
            if (circle.getCenterX() + circle.getRadius() * 2 > 200) {
   
                borderPane.setTop(text);
                return;
            }
            circle.setCenterX(circle.getCenterX() + circle.getRadius());
        });

        up.setOnAction(e -> {
   
            borderPane.setTop(null);
            if (circle.getCenterY() - circle.getRadius() * 2 < 0) {
   
                borderPane.setTop(text);
                return;
            }
            circle.setCenterY(circle.getCenterY() - circle.getRadius());
        });

        down.setOnAction(e -> {
   
            borderPane.setTop(null);
            if (circle.getCenterY() + circle.getRadius() * 2 > 150) {
   
                borderPane.setTop(text);
                return;
            }
            circle.setCenterY(circle.getCenterY() + circle.getRadius());
        });

        // 把Nodes添加到borderPane中
        borderPane.setCenter(pane);
        borderPane.setBottom(hBox);

        Scene scene = new Scene(borderPane, 200, 150);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }
}

输出结果:

在这里插入图片描述

*15.4 (创建一个简单的计算)

编写一个程序完成加法、减法、乘法和除法操作,参见图15-25a

package com.example.demo;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Test extends Application {
   
    @Override
    public void start(Stage pStage) {
   
        // hBox1用来储存输入行,hBox2用来储存按钮,text警告会在除数为0时弹出,以上三个Node都会被放置在borderPane中
        HBox hBox1 = new HBox();
        HBox hBox2 = new HBox();
        Text text = new Text("Divisor cannot be 0!");
        text.setFill(Color.RED);
        BorderPane borderPane = new BorderPane();

        // 创建输入行并添加到面板
        Text num1 = new Text("Number 1");
        TextField num1Field = new TextField();
        Text num2 = new Text("Number 2");
        TextField num2Field = new TextField();
        Text result = new Text("Result");
        TextField resultField = new TextField();
        // 禁止输入
        resultField.setEditable(false);
        hBox1.getChildren().addAll(num1, num1Field, num2, num2Field, result, resultField);
        hBox1.setSpacing(10);
        hBox1.setAlignment(Pos.CENTER);

        // 添加按钮
        Button add = new Button("Add");
        Button sub = new Button("Subtract");
        Button multi = new Button("Multiply");
        Button div = new Button("Divide");
        hBox2.getChildren().addAll(add, sub, multi, div);
        hBox2.setSpacing(20);
        hBox2.setAlignment(Pos.CENTER);

        // 点击按钮计算
        add.setOnAction(e -> {
   
            // 移除可能存在的警告
            borderPane.getChildren().remove(text);
            double num1Value = Double.parseDouble(num1Field.getText());
            double num2Value = Double.parseDouble(num2Field.getText());
            double resultValue = num1Value + num2Value;
            resultField.setText("" + resultValue);
        });

        sub.setOnAction(e -> {
   
            // 移除可能存在的警告
            borderPane.getChildren().remove(text);
            double num1Value = Double.parseDouble(num1Field.getText());
            double num2Value = Double.parseDouble(num2Field.getText());
            double resultValue = num1Value - num2Value;
            resultField.setText("" + resultValue);
        });

        multi.setOnAction(e -> {
   
            // 移除可能存在的警告
            borderPane.getChildren().remove(text);
            double num1Value = Double.parseDouble(num1Field.getText());
            double num2Value = Double.parseDouble(num2Field.getText());
            double resultValue = num1Value * num2Value;
            resultField.setText("" + resultValue);
        });

        div.setOnAction(e -> {
   
            // 移除可能存在的警告
            borderPane.getChildren().remove(text);
            double num1Value = Double.parseDouble(num1Field.getText());
            double num2Value = Double.parseDouble(num2Field.getText());
            if (num2Value == 0) {
   
                // 如果除数为0,弹出警告,并且清除上一轮计算的结果信息,注意,弹出警告之后,进行下次其他计算前需要移除
                borderPane.setTop(text);
                resultField.clear();
                // 文字居中
                BorderPane.setAlignment(text, Pos.CENTER);
                return;
            }
            double resultValue = num1Value / num2Value;
            resultField.setText("" + resultValue);
        });

        // 把Nodes添加到borderPane中
        borderPane.setCenter(hBox1);
        borderPane.setBottom(hBox2);

        Scene scene = new Scene(borderPane, 300, 150);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }
}

输出结果:

在这里插入图片描述

*15.5(创建一个投资值计算器)

编写一个程序,计算投资值在给定利率以及给定年数下的未来值。计算的公式如下所示:

未来值 = 投资值 × ( 1 + 月利率 ) 年数 × 12 未来值 = 投资值 × (1 + 月利率)^{年数 × 12} 未来值=投资值×(1+月利率)年数×12

使用文本域显示利率、投资值和年数。当用户单击Calculate按钮时在文本域显示未来值,如图15-25b所示

package com.example.demo;

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

import java.text.DecimalFormat;

public class Test extends Application {
   
    // 创建输入文本框
    TextField amountField = new TextField();
    TextField yearsField = new TextField();
    TextField rateField = new TextField();
    TextField valueField = new TextField();

    @Override
    public void start(Stage pStage) {
   
        // gridPane用来储存按钮
        GridPane gridPane = new GridPane();
        gridPane.setVgap(5);
        gridPane.setHgap(5);

        // 添加输入行到面板
        gridPane.add(new Label("Investment Amount:"), 0, 0);
        gridPane.add(amountField, 1, 0);
        gridPane.add(new Label("Number of Years:"), 0, 1);
        gridPane.add(yearsField, 1, 1);
        gridPane.add(new Label("Annual Interest Rate:"), 0, 2);
        gridPane.add(rateField, 1, 2);
        gridPane.add(new Label("Future Value:"), 0, 3);
        gridPane.add(valueField, 1, 3);
        Button button = new Button("Calculate");
        gridPane.add(button, 1, 4);

        // 禁止输入
        valueField.setEditable(false);
        // 位置调整
        gridPane.setAlignment(Pos.CENTER);
        GridPane.setHalignment(button, HPos.RIGHT);

        // 点击按钮计算
        button.setOnAction(e -> {
   
            calculate();
        });

        Scene scene = new Scene(gridPane, 300, 150);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }

    public void calculate() {
   
        double amount = Double.parseDouble(amountField.getText());
        double years = Double.parseDouble(yearsField.getText());
        double rate = Double.parseDouble(rateField.getText());
        double futureValue = amount * Math.pow((1 + rate / 12), (years * 12));
        // 将数字格式化为字符串,禁用科学计数法
        DecimalFormat decimalFormat = new DecimalFormat();
        String formattedNumber = decimalFormat.format(futureValue);
        valueField.setText("$" + formattedNumber);
    }
}

输出结果:

在这里插入图片描述

**15.6(两个消息交替出现)

编写一个程序,当单击鼠标时面板上交替显示两个文本"Java is fun"和"Java is powerful"

package com.example.demo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Test extends Application {
   
    @Override
    public void start(Stage pStage) {
   
        StackPane pane = new StackPane();
        Text text = new Text("Java is fun");
        pane.getChildren().add(text);

        // setOnMousePressed方法在按下鼠标键时会完成指定动作,setOnMouseClicked方法必须按下并释放鼠标才会完成指定动作
        text.setOnMousePressed(e -> {
   
            if (text.getText().length() == 11)
                text.setText("Java is powerful");
            else
                text.setText("Java is fun");
        });

        Scene scene = new Scene(pane, 100, 100);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }
}

输出结果:

在这里插入图片描述

15.7(使用鼠标改变颜色)

编写一个程序,显示一个圆的颜色,当按下鼠标键时颜色为黑色,释放鼠标时颜色为白色

package com.example.demo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Test extends Application {
   
    @Override
    public void start(Stage pStage) {
   
        StackPane pane = new StackPane();
        Circle circle = new Circle(20);
        pane.getChildren().add(circle);
        circle.setOnMousePressed(e -> {
   
            if (circle.getFill() == Color.BLACK) {
   
                circle.setFill(Color.TRANSPARENT);
                circle.setStroke(Color.BLACK);
            }
            else
                circle.setFill(Color.BLACK);
        });

        Scene scene = new Scene(pane, 100, 100);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }
}

输出结果:

在这里插入图片描述

*15.8(显示鼠标的位罝)

编写两个程序,一个当单击鼠标时显示鼠标的位置(参见图15-26a),而另一个当按下鼠标时显示鼠标的位置,当释放鼠标时停止显示

第一个程序

package com.example.demo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Test extends Application {
   
    @Override
    public void start(Stage pStage) {
   
        Text text = new Text();
        Pane pane = new Pane();
        // e是一个MouseEvent对象,它代表鼠标事件的信息,包括鼠标的位置、点击类型、按键状态等
        pane.setOnMousePressed(e -> {
   
            pane.getChildren().remove(text);
            double x = e.getX();
            double y = e.getY();
            String info = x + ", " + y;
            text.setX(x);
            text.setY(y);
            text.setText(info);
            pane.getChildren().add(text);
        });

        Scene scene = new Scene(pane, 100, 100);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }
}

第二个程序

package com.example.demo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Test extends Application {
   
    @Override
    public void start(Stage pStage) {
   
        Text text = new Text();
        Pane pane = new Pane();

        // e是一个MouseEvent对象,它代表鼠标事件的信息,包括鼠标的位置、点击类型、按键状态等
        pane.setOnMousePressed(e -> {
   
            if (e.getButton() == MouseButton.PRIMARY) {
   
                double x = e.getX();
                double y = e.getY();
                String info = x + ", " + y;
                text.setX(x);
                text.setY(y);
                text.setText(info);
                pane.getChildren().add(text);
            }
        });

        // 松开时消失
        pane.setOnMouseReleased(e -> {
   
            if (e.getButton() == MouseButton.PRIMARY) {
   
                pane.getChildren().remove(text);
            }
        });

        Scene scene = new Scene(pane, 100, 100);
        pStage.setTitle("Test Program");
        pStage.setScene(scene);
        pStage.show();
    }
}

输出结果:

在这里插入图片描述

*15.9 (使用箭头键画线)

请编写一个程序,使用箭头键绘制线段。所画的线从面板的中心开始,当敲 击向右、向上、向左或向下的箭头键时,相应地向东、向北、向西或向南方向画线,如图 15-26b所示

package com.example.demo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class Test extends Application {
   
    // locationX是初始的X坐标,locationY是初始的Y坐标,upMove等4个int是移动的距离,把这些数据放到开头是因为有访问权限的问题
    double locationX = 100;
    double locationY = 100;
    Pane pane = new Pane();
    int upMove = 5;
    int downMove = 5;
    int leftMove = 5;
    int rightMove = 5;

    @Override
    public void start(Stage primaryStage) {
   
        Scene scene = new Scene(pane, 200, 200);

        // 调用move方法,其中code代表了上下左右按键
        scene.setOnKeyPressed(e -> {
   
            KeyCode code = e.getCode();
            move(code);
        });

        primaryStage.setScene(scene);
        primaryStage.setTitle("Draw Lines");
        primaryStage.show();
    }

    public void move(KeyCode code) {
   
        switch (code) {
   
            // 当用户点击"向上箭头",绘制一条直线,startX和startY坐标是Scene的中心(或者是上一次按键所形成直线的endX和endY坐标),同时按照逻辑更新endX和endY坐标,作为下一次按键的初始点
            case UP:
                Line upLine = new Line(locationX, locationY, locationX, locationY - upMove);
                pane.getChildren(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值