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