JavaFX、动画:双向链表

 

package list;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polyline;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class Exercise24_11 extends Application {
    private Text text = new Text();                 //顶部文本
    private TextField value = new TextField();      //结点值
    private TextField index = new TextField();      //结点下标
    private Button search = new Button("Search");   //搜索
    private Button insert = new Button("Insert");   //插入
    private Button delete = new Button("Delete");   //删除
    private Button forwardTraversal = new Button("Forward Traversal");      //前向遍历
    private Button backwardTraversal = new Button("Backward Traversal");    //后向遍历
    private LinkedList<Object> linkedList = new LinkedList<>();     //链表

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

    @Override
    public void start(Stage primaryStage) {
        value.setPrefColumnCount(3);
        index.setPrefColumnCount(2);
        HBox  hBox = new HBox(10, new Label("Enter a value:"), value,   //底部面板
                new Label("Enter an index:"), index, search, insert, delete, forwardTraversal, backwardTraversal);
        hBox.setAlignment(Pos.CENTER);

        BorderPane pane = new BorderPane(getCenter());      //总面板
        pane.setTop(text);
        pane.setBottom(hBox);
        BorderPane.setAlignment(pane.getTop(), Pos.CENTER);
        pane.setPadding(new Insets(5));

        //按钮注册动作事件
        search.setOnAction(event -> search());
        insert.setOnAction(event -> {insert(); pane.setCenter(getCenter());});
        delete.setOnAction(event -> {delete(); pane.setCenter(getCenter());});
        forwardTraversal.setOnAction(event -> forwardTraversal());
        backwardTraversal.setOnAction(event -> backwardTraversal());

        Scene scene = new Scene(pane, 800, 350);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Exercise24_11");
        primaryStage.show();
    }

    /** 返回中心面板 */
    private Pane getCenter() {
        HBox hBox = new HBox();     //结点面板
        hBox.setAlignment(Pos.CENTER);
        for (int i = 0; i < linkedList.size(); i++)     //添加结点
            hBox.getChildren().add(getNode(i));
        hBox.relocate(50, 150);

        Group head = pointer("head", false);    //指针
        Group tail = pointer("tail", true);
        head.relocate(20, 100);
        hBox.widthProperty().addListener(observable -> tail.relocate(hBox.getWidth() - 20, 100));

        Pane pane = new Pane(hBox);     //总面板
        pane.setStyle("-fx-padding: 10px;");

        if (linkedList.size() > 0)      //链表大小大于0时,添加指针
            pane.getChildren().addAll(head, tail);

        return pane;
    }

    /** 返回结点 */
    private Group getNode(int index) {
        final int SIZE = 3;
        VBox vBox = new VBox();     //单结点面板
        vBox.setAlignment(Pos.CENTER);

        //结点
        Label[] labels = new Label[SIZE];
        Rectangle[] rectangles = new Rectangle[SIZE];
        for (int i = 0; i < SIZE; i++) {
            rectangles[i] = new Rectangle(70, 25);
            rectangles[i].setStyle("-fx-stroke: grey; -fx-fill: white;");
            labels[i] = new Label("", rectangles[i]);
            labels[i].setContentDisplay(ContentDisplay.CENTER);
            vBox.getChildren().add(labels[i]);
        }
        labels[0].setText(String.valueOf(linkedList.get(index)));
        labels[1].setText("next");
        labels[2].setText("previous");

        //后结点指针,前结点指针
        Line next = new Line(70, 40, 100, 10);
        Polyline nextArrow = new Polyline(80, 10, 100, 10, 100, 30);
        Line previous = new Line(100, 70, 71, 10);
        Polyline previousArrow = new Polyline(65, 30, 71, 10, 91, 18);

        Group group = new Group(vBox);
        if (index < linkedList.size() - 1)  //除末尾结点外,添加结点指针
            group.getChildren().addAll(next, nextArrow, previous, previousArrow);

        return group;
    }

    /** 返回头、尾指针 */
    private Group pointer(String text, boolean rotated) {
        Line line = new Line(150, 113, 200, 113);   //指针
        Polyline arrow = new Polyline(185, 100, 200, 113, 185, 126);
        Label label = new Label(text);
        label.setRotate(-75);
        label.relocate(120, 105);

        Group group = new Group(line, arrow, label);
        group.setRotate(75);

        if (rotated) {  //处理尾指针
            group.setRotate(group.getRotate() + 40);
            label.setRotate(label.getRotate() - 38);
        }

        return group;
    }

    /** 查找结点值 */
    private void search() {
        String v = value.getText().trim();

        if (v.length() > 0) //结点值非空
            text.setText("LinkList " + (linkedList.contains(v) ? "contains ": "does not contain ") + v +
                    (linkedList.contains(v) ? " (index: " + linkedList.indexOf(v) + ")": ""));
        else
            text.setText("Enter a value, please");
        value.setText("");
    }

    /** 插入结点 */
    private void insert() {
        String value = this.value.getText().trim();

        text.setText("");
        if (value.length() == 0)    //结点值为空
            text.setText("Value can not be empty");
        else {
            String i = this.index.getText().trim();
            if (i.length() == 0) {  //未指定下标,添加到末尾
                linkedList.addLast(value);
                this.value.setText("");
            } else {
                try {
                    int index = Integer.parseInt(this.index.getText().trim());  //获取下标
                    if (0 <= index && index <= linkedList.size()) { //下标合法
                        linkedList.add(index, value);
                        this.value.setText("");
                        this.index.setText("");
                    } else {
                        text.setText("Index " + index + " out of bounds");
                        this.index.setText("");
                    }
                } catch (NumberFormatException ex) {}
            }
        }
    }

    /** 删除结点 */
    private void delete() {
        String value = this.value.getText().trim();

        text.setText("");
        if (value.length() != 0) {  //结点值非空
            this.value.setText("");
            this.index.setText("");
            text.setText(linkedList.remove(value) ? value + " has been removed" : value + " does not exist");
        } else {
            try {
                int index = Integer.parseInt(this.index.getText().trim());  //获取下标
                if (0 <= index && index < linkedList.size()) {  //下标合法
                    Object v =  linkedList.remove(index);   //删除指定下标结点
                    this.value.setText("");
                    this.index.setText("");
                    text.setText("index " + index + " has been removed(value: " + v + ")");
                } else
                    text.setText("index " + index + " out of bounds");
            } catch (NumberFormatException ex) {}
        }
    }

    /** 前向遍历 */
    private void forwardTraversal() {
        String text = "Forward Traversal:";
        ListIterator<Object> iterator = linkedList.listIterator();
        while (iterator.hasNext())
            text += " " + iterator.next();
        this.text.setText(text);
    }

    /** 后向遍历 */
    private void backwardTraversal() {
        String text = "Backward Traversal:";
        ListIterator<Object> iterator = linkedList.listIterator(linkedList.size());
        while (iterator.hasPrevious())
            text += " " + iterator.previous();
        this.text.setText(text);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值