package com.ht.ui.user;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.TimelineBuilder;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToolBar;
import javafx.scene.control.Tooltip;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.util.Callback;
import javafx.util.Duration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ht.ui.MainApplication;
import com.ht.ui.property.SimpleBeanBooleanProperty;
import com.ht.ui.property.SimpleBeanStringProperty;
import com.ht.ui.util.HessianResponseService;
import com.ht.ui.util.HessianResponseTask;
import com.ht.ui.util.MessageConstants;
import com.ht.ui.util.RedoUndoManager;
import com.ht.util.UserSession;
import com.ht.web.hessian.HessianFactoryManger;
import com.ht.web.mongo.domain.User;
import com.ht.web.mongo.domain.UserGroup;
import com.ht.web.remoting.HessianResponse;

public class UserGroupEditor extends VBox {
	private static final Logger log = LoggerFactory
			.getLogger(UserGroupEditor.class);

	private TableView<UserGroupProperty> userTableView;
	private ObservableList<UserGroupProperty> data;

	private TableColumn<UserGroupProperty, String> nameCol;

	private TableColumn<UserGroupProperty, Boolean> ykCol;
	private TableColumn<UserGroupProperty, Boolean> ytCol;
	private TableColumn<UserGroupProperty, Boolean> blinkingResetCol;
	private TableColumn<UserGroupProperty, Boolean> alarmAffirmCol;

	private TableColumn<UserGroupProperty, Boolean> oprateRecordCol;
	private TableColumn<UserGroupProperty, Boolean> alarmRecordCol;
	private TableColumn<UserGroupProperty, Boolean> energyStatisticCol;

	private TableColumn<UserGroupProperty, Boolean> userEditCol;

	private Label message;
	private Timeline messageAnimate;

	// private Set<UserGroup> changedUserGroupSet = new
	// HashSet<UserGroupEditor.UserGroup>();
	// private Set<UserGroup> deletedUserGroupSet = new
	// HashSet<UserGroupEditor.UserGroup>();

	private List<UserGroupProperty> addedUserGroup = new ArrayList<UserGroupEditor.UserGroupProperty>();
	// private Map<String, Map<String, Object>> changedUserGroup = new
	// HashMap<String, Map<String, Object>>();
	private List<UserGroupProperty> deletedUserGroup = new ArrayList<UserGroupProperty>();

	private RedoUndoManager redoUndoManager;
	private EventHandler<TableColumn.CellEditEvent<UserGroupProperty, Boolean>> booleanCellEditHandler;;

	public UserGroupEditor() {
		super(5);
		
		setAlignment(Pos.CENTER);

		// 创建工具栏
		createToolBar();
		// 用户组列表
		createTablePanel();
		// 添加用户组
		createAddPanel();
		// 操作按钮
		createBottomButton();
	}

	private void createToolBar() {
		ToolBar toolbar = new ToolBar();
		toolbar.getStyleClass().add("mini-toolbar");

		Button undoButton = new Button();
		undoButton.setGraphic(new ImageView(new Image(MainApplication.class
				.getResourceAsStream("images/back.png"))));
		undoButton.setTooltip(new Tooltip("撤消"));
		undoButton.setOnAction(new EventHandler<ActionEvent>() {
			public void handle(ActionEvent event) {
				// back();
				redoUndoManager.undo();
			}
		});
		undoButton.setMaxHeight(Double.MAX_VALUE);

		Button redoButton = new Button();
		redoButton.setGraphic(new ImageView(new Image(MainApplication.class
				.getResourceAsStream("images/forward.png"))));
		redoButton.setTooltip(new Tooltip("重做"));
		redoButton.setOnAction(new EventHandler<ActionEvent>() {
			public void handle(ActionEvent event) {
				// forward();
				redoUndoManager.redo();
			}
		});

		Button reloadButton = new Button();
		reloadButton.setGraphic(new ImageView(new Image(getClass()
				.getResourceAsStream("/com/ht/ui/images/reload.png"))));
		reloadButton.setOnAction(new EventHandler<ActionEvent>() {
			public void handle(ActionEvent event) {
				reload();
			}

		});
		reloadButton.setMaxHeight(Double.MAX_VALUE);

		redoUndoManager = new RedoUndoManager(undoButton, redoButton);

		toolbar.getItems().addAll(undoButton, redoButton, reloadButton);

		getChildren().add(toolbar);
	}

	private void createBottomButton() {

		Button saveBtn = new Button("保存");
		saveBtn.setPrefWidth(80);
		saveBtn.setOnAction(new EventHandler<ActionEvent>() {

			@Override
			public void handle(ActionEvent event) {

				if (UserSession.INSTANCE.getUser() == null) {

					UserLoginDialog.getInstance().showDialog(null,
							"您已自动退出, 请重新登录.");
				} else {
					User user = UserSession.INSTANCE.getUser();
					if (user != null && !user.getGroup().getUserEdit()) {
						showMessage("您所在的用户组没有权限执行该操作");
						return;
					}

					final List<UserGroup> addOrUpdateList = new ArrayList<UserGroup>();
					for (UserGroupProperty group : addedUserGroup) {
						addOrUpdateList.add(group.getUserGroup());
					}

					final List<UserGroup> deletedList = new ArrayList<UserGroup>();
					for (UserGroupProperty group : deletedUserGroup) {
						deletedList.add(group.getUserGroup());
					}

					try {
						HessianResponse resp = HessianFactoryManger.INSTANCE
								.getUserService().addOrUpdateAllGroups(
										deletedList, addOrUpdateList);

						if (resp.isSuccessful()) {

							if (!resp.getMsg().isEmpty()) {
								showMessage(resp.getMsg());
							}
							deletedUserGroup.clear();
							addedUserGroup.clear();
							redoUndoManager.reset();
							reload();
						} else {
							if (resp.isLogin()) {

								UserLoginDialog.getInstance().showDialog(null,
										resp.getMsg());
							} else {
								showMessage(resp.getMsg());
							}
						}
					} catch (Exception e) {
						showMessage(MessageConstants.ERROR_SERVER_ERROR);
					}
				}
			}
		});
		
		getChildren().add(saveBtn);
	}

	private void createTablePanel() {
		Callback<TableColumn<UserGroupProperty, Boolean>, TableCell<UserGroupProperty, Boolean>> checkBoxCellFactory = new Callback<TableColumn<UserGroupProperty, Boolean>, TableCell<UserGroupProperty, Boolean>>() {

			@Override
			public TableCell<UserGroupProperty, Boolean> call(
					final TableColumn<UserGroupProperty, Boolean> param) {
				return new CheckBoxCell();
			}
		};

		userTableView = new TableView<UserGroupProperty>();
		userTableView.setEditable(true);
		userTableView.getSelectionModel()
				.setSelectionMode(SelectionMode.SINGLE);
		userTableView.getSelectionModel().setCellSelectionEnabled(false);
		VBox.setVgrow(userTableView, Priority.ALWAYS);

		// 初始化Boolean型单元格编辑处理函数
		booleanCellEditHandler = new BooleanCellEditEventHandler();

		crateTableBaseColumns();

		createTableViewColumns(checkBoxCellFactory);

		createTableOprateColumns(checkBoxCellFactory);

		createTableManageColumns(checkBoxCellFactory);

		// data = FXCollections.observableArrayList(new UserGroup("高级管理员", true,
		// true, true), new UserGroup("普通管理员", true, true, true),
		// new UserGroup("普通用户", false, false, false));

		data = FXCollections.observableArrayList();
		userTableView.setItems(data);

		ContextMenu contextMenu = new ContextMenu();
		MenuItem deleteItem = new MenuItem("删除");
		deleteItem.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				deleteSelectedUserGroup();
			}
		});
		contextMenu.getItems().add(deleteItem);
		userTableView.setContextMenu(contextMenu);

//		getChildren().add(userTableView);

		ProgressIndicator progress = new ProgressIndicator();
		progress.setMaxSize(150, 150);
		Region veil = new Region();
		veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.4)");
		
		StackPane stackPane = new StackPane();
		VBox.setVgrow(stackPane, Priority.ALWAYS);
		stackPane.getChildren().addAll(userTableView, veil, progress);
		getChildren().add(stackPane);
		
		progress.progressProperty().bind(service.progressProperty());
        veil.visibleProperty().bind(service.runningProperty());
        progress.visibleProperty().bind(service.runningProperty());
	}

	private void crateTableBaseColumns() {

		Callback<TableColumn<UserGroupProperty, String>, TableCell<UserGroupProperty, String>> cellFactory = new Callback<TableColumn<UserGroupProperty, String>, TableCell<UserGroupProperty, String>>() {
			public TableCell<UserGroupProperty, String> call(
					TableColumn<UserGroupProperty, String> p) {
				return new EditingCell();
			}
		};

		nameCol = new TableColumn<UserGroupProperty, String>("名称");
		nameCol.setEditable(false);
		nameCol.setMinWidth(100);
		nameCol.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, String>(
				"name"));

		userTableView.getColumns().add(nameCol);
	}

	@SuppressWarnings("unchecked")
	private void createTableViewColumns(
			Callback<TableColumn<UserGroupProperty, Boolean>, TableCell<UserGroupProperty, Boolean>> checkBoxCellFactory) {

		oprateRecordCol = new TableColumn<UserGroupProperty, Boolean>("操作记录");
		oprateRecordCol.setMinWidth(80);
		oprateRecordCol
				.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
						"oprateRecord"));
		oprateRecordCol.setCellFactory(checkBoxCellFactory);
		oprateRecordCol.setOnEditCommit(booleanCellEditHandler);

		alarmRecordCol = new TableColumn<UserGroupProperty, Boolean>("报警记录");
		alarmRecordCol.setMinWidth(80);
		alarmRecordCol
				.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
						"alarmRecord"));
		alarmRecordCol.setCellFactory(checkBoxCellFactory);
		alarmRecordCol.setOnEditCommit(booleanCellEditHandler);

		energyStatisticCol = new TableColumn<UserGroupProperty, Boolean>("能耗统计");
		energyStatisticCol.setMinWidth(80);
		energyStatisticCol
				.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
						"energyStatistic"));
		energyStatisticCol.setCellFactory(checkBoxCellFactory);
		energyStatisticCol.setOnEditCommit(booleanCellEditHandler);

		TableColumn<UserGroupProperty, Boolean> viewCol = new TableColumn<UserGroupProperty, Boolean>(
				"查看权限");
		viewCol.getColumns().addAll(oprateRecordCol, alarmRecordCol,
				energyStatisticCol);
		userTableView.getColumns().add(viewCol);
	}

	private void createTableOprateColumns(
			Callback<TableColumn<UserGroupProperty, Boolean>, TableCell<UserGroupProperty, Boolean>> checkBoxCellFactory) {
		ykCol = new TableColumn<UserGroupProperty, Boolean>("遥控操作");
		ykCol.setMinWidth(80);
		ykCol.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
				"yk"));
		ykCol.setCellFactory(checkBoxCellFactory);
		ykCol.setOnEditCommit(booleanCellEditHandler);

		ytCol = new TableColumn<UserGroupProperty, Boolean>("遥调操作");
		ytCol.setMinWidth(80);
		ytCol.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
				"yt"));
		ytCol.setCellFactory(checkBoxCellFactory);
		ytCol.setOnEditCommit(booleanCellEditHandler);

		blinkingResetCol = new TableColumn<UserGroupProperty, Boolean>("闪烁复归");
		blinkingResetCol.setMinWidth(80);
		blinkingResetCol
				.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
						"blinkingReset"));
		blinkingResetCol.setCellFactory(checkBoxCellFactory);
		blinkingResetCol.setOnEditCommit(booleanCellEditHandler);

		alarmAffirmCol = new TableColumn<UserGroupProperty, Boolean>("报警确认");
		alarmAffirmCol.setMinWidth(80);
		alarmAffirmCol
				.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
						"alarmAffirm"));
		alarmAffirmCol.setCellFactory(checkBoxCellFactory);
		alarmAffirmCol.setOnEditCommit(booleanCellEditHandler);

		TableColumn<UserGroupProperty, Boolean> handleCol = new TableColumn<UserGroupProperty, Boolean>(
				"操作权限");
		handleCol.getColumns().addAll(ykCol, ytCol, blinkingResetCol,
				alarmAffirmCol);

		userTableView.getColumns().add(handleCol);
	}

	private void createTableManageColumns(
			Callback<TableColumn<UserGroupProperty, Boolean>, TableCell<UserGroupProperty, Boolean>> checkBoxCellFactory) {
		userEditCol = new TableColumn<UserGroupProperty, Boolean>("用户管理");
		userEditCol.setMinWidth(80);
		userEditCol
				.setCellValueFactory(new PropertyValueFactory<UserGroupProperty, Boolean>(
						"userEdit"));
		userEditCol.setCellFactory(checkBoxCellFactory);
		userEditCol.setOnEditCommit(booleanCellEditHandler);

		userTableView.getColumns().add(userEditCol);
	}

	private void createAddPanel() {
		HBox hb = new HBox(3);
		hb.setAlignment(Pos.CENTER_LEFT);

		final TextField nameText = new TextField();
		nameText.setPromptText("名称");
		nameText.setMaxHeight(28);
		nameText.setPrefWidth(nameCol.getMinWidth());
		nameText.setOnKeyReleased(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent t) {
				if (t.getCode() == KeyCode.ENTER) {
					final UserGroupProperty group = new UserGroupProperty(
							nameText.getText());
					nameText.setText("");

					addNewUserGroup(group);
				}
			}
		});

		final Button addButton = new Button("添加");
		addButton.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent e) {

				final UserGroupProperty group = new UserGroupProperty(nameText
						.getText());
				nameText.setText("");

				addNewUserGroup(group);
			}
		});

		message = new Label();
		message.getStyleClass().add("message");
		message.setOpacity(0);
		messageAnimate = TimelineBuilder
				.create()
				.keyFrames(
						new KeyFrame(Duration.seconds(.5),
								new EventHandler<ActionEvent>() {

									public void handle(ActionEvent t) {
									}
								}, new KeyValue(message.opacityProperty(), 0,
										Interpolator.EASE_BOTH))).build();
		messageAnimate.setDelay(Duration.seconds(3));
		hb.getChildren().addAll(nameText, addButton, message);

		getChildren().add(hb);
	}

	private void addNewUserGroup(final UserGroupProperty group) {

		Runnable undo = new Runnable() {

			@Override
			public void run() {
				addedUserGroup.remove(group);
				data.remove(group);

			}
		};

		Runnable redo = new Runnable() {

			@Override
			public void run() {
				addedUserGroup.add(group);
				data.add(group);

			}
		};

		redoUndoManager.updateUndoRedoList(undo, redo);

		redo.run();
	}

	private void deleteSelectedUserGroup() {
		final UserGroupProperty deletedGroup = userTableView
				.getSelectionModel().getSelectedItem();

		final boolean isAddOrUpdate = addedUserGroup.contains(deletedGroup);

		Runnable undo = new Runnable() {

			@Override
			public void run() {

				if (isAddOrUpdate) {
					addedUserGroup.add(deletedGroup);
				}
				if (deletedGroup.getUserGroup().getId() != null) {
					deletedUserGroup.remove(deletedGroup);
				}
				data.add(deletedGroup);
			}
		};

		Runnable redo = new Runnable() {

			@Override
			public void run() {
				if (isAddOrUpdate) {
					addedUserGroup.remove(deletedGroup);
				}
				if (deletedGroup.getUserGroup().getId() != null) {
					deletedUserGroup.add(deletedGroup);
				}
				data.remove(deletedGroup);
			}
		};

		redoUndoManager.updateUndoRedoList(undo, redo);
		redo.run();
	}

	public void changeUserGroup(final UserGroupProperty group,
			final boolean oldValue, final boolean newValue,
			final BooleanProperty property) {
		final boolean isAddOrUpdate = addedUserGroup.contains(group);

		Runnable undo = new Runnable() {

			@Override
			public void run() {
				property.setValue(oldValue);
				if (!isAddOrUpdate) {
					addedUserGroup.remove(group);
				}
			}
		};

		Runnable redo = new Runnable() {

			@Override
			public void run() {
				property.setValue(newValue);
				if (!isAddOrUpdate) {
					addedUserGroup.add(group);
				}
			}
		};

		redoUndoManager.updateUndoRedoList(undo, redo);
		redo.run();
	}

	private void showMessage(String content) {
		message.setText(content);
		message.setOpacity(1);
		messageAnimate.play();
	}
	
	private HessianResponseService service = new HessianResponseService() {
		
		@Override
		protected Task<HessianResponse> createTask() {
			return new HessianResponseTask() {
				
				@Override
				protected HessianResponse call() throws Exception {
					try {
						return HessianFactoryManger.INSTANCE
								.getUserService().getAllGroups();
					} catch (Exception e) {
						e.printStackTrace();
					}
					return null;
				}
				
				@Override
				public void successResponse(HessianResponse resp) {
					userTableView.getItems().clear();
					
					List<UserGroup> groups = (List<UserGroup>) resp.getData();
					for (UserGroup group : groups) {
						userTableView.getItems().add(new UserGroupProperty(group));
					}
				}
				
				@Override
				public void nullResponse() {
					showMessage(MessageConstants.ERROR_APP_ERROR);
				}
				
				@Override
				public void failureResponse(HessianResponse resp) {
					if (resp.isLogin()) {
						showMessage(resp.getMsg());
					} else {
						UserLoginDialog.getInstance().showDialog(null,
								resp.getMsg());
					}
				}
			};
		}
	};

	public void reload() {
		service.restart();
	}

	public static class UserGroupProperty {
		private UserGroup userGroup;

		private StringProperty name;

		// 浏览权限
		private BooleanProperty oprateRecord;// 操作记录
		private BooleanProperty alarmRecord;// 报警记录
		private BooleanProperty energyStatistic;// 能耗统计

		// 管理权限
		private BooleanProperty userEdit;// 用户管理

		// 操作权限
		private BooleanProperty yk;
		private BooleanProperty yt;
		private BooleanProperty blinkingReset;
		private BooleanProperty alarmAffirm;

		public UserGroupProperty(UserGroup userGroup) {
			this.userGroup = userGroup;

			this.name = new SimpleBeanStringProperty(userGroup, "name");

			this.userEdit = new SimpleBeanBooleanProperty(userGroup, "userEdit");

			this.yk = new SimpleBeanBooleanProperty(userGroup, "yk");
			this.yt = new SimpleBeanBooleanProperty(userGroup, "yt");
			this.blinkingReset = new SimpleBeanBooleanProperty(userGroup,
					"blinkingReset");
			this.alarmAffirm = new SimpleBeanBooleanProperty(userGroup,
					"alarmAffirm");

			this.oprateRecord = new SimpleBeanBooleanProperty(userGroup,
					"oprateRecord");
			this.alarmRecord = new SimpleBeanBooleanProperty(userGroup,
					"alarmRecord");
			this.energyStatistic = new SimpleBeanBooleanProperty(userGroup,
					"energyStatistic");
		}

		public UserGroupProperty(String name) {
			this(new UserGroup(name));

		}

		public UserGroup getUserGroup() {
			return userGroup;
		}

		public StringProperty nameProperty() {
			return name;
		}

		public BooleanProperty oprateRecordProperty() {
			return oprateRecord;
		}

		public BooleanProperty alarmRecordProperty() {
			return alarmRecord;
		}

		public BooleanProperty energyStatisticProperty() {
			return energyStatistic;
		}

		public BooleanProperty userEditProperty() {
			return userEdit;
		}

		public BooleanProperty ykProperty() {
			return yk;
		}

		public BooleanProperty ytProperty() {
			return yt;
		}

		public BooleanProperty blinkingResetProperty() {
			return blinkingReset;
		}

		public BooleanProperty alarmAffirmProperty() {
			return alarmAffirm;
		}

	}

	private class BooleanCellEditEventHandler implements
			EventHandler<TableColumn.CellEditEvent<UserGroupProperty, Boolean>> {
		@Override
		public void handle(CellEditEvent<UserGroupProperty, Boolean> event) {
			final UserGroupProperty group = event.getRowValue();

			final boolean oldValue = event.getOldValue();
			final boolean newValue = event.getNewValue();

			String propertyName = ((PropertyValueFactory) event
					.getTableColumn().getCellValueFactory()).getProperty();
			try {
				String methodName = propertyName + "Property";
				BooleanProperty property = (BooleanProperty) group.getClass()
						.getMethod(methodName, new Class[] {}).invoke(group);
				changeUserGroup(group, oldValue, newValue, property);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
		}
	}

	class CheckBoxCell extends TableCell<UserGroupProperty, Boolean> {

		private CheckBox checkBox;

		public CheckBoxCell() {

			checkBox = new CheckBox("允许");

			checkBox.selectedProperty().addListener(
					new ChangeListener<Boolean>() {
						@Override
						public void changed(
								ObservableValue<? extends Boolean> observable,
								Boolean oldValue, Boolean newValue) {
							checkBox.setText(checkBox.isSelected() ? "允许"
									: "禁止");
						}
					});
			checkBox.setSelected(true);
			checkBox.setOnAction(new EventHandler<ActionEvent>() {
				@Override
				public void handle(ActionEvent event) {
					commitEdit(checkBox.isSelected());
				}
			});

		}

		@Override
		public void startEdit() {
			super.startEdit();
			if (isEmpty()) {
				return;
			}

			checkBox.setSelected(getItem());
			checkBox.setTextFill(getItem() ? Color.LAWNGREEN : Color.FIREBRICK);
			setGraphic(checkBox);
			setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
		}

		@Override
		public void cancelEdit() {
			super.cancelEdit();

			// setGraphic(label);
			setContentDisplay(ContentDisplay.TEXT_ONLY);
		}

		@Override
		protected void updateItem(Boolean item, boolean empty) {
			super.updateItem(item, empty);
			if (!isEmpty()) {

				if (item != null) {
					setText(item ? "允许" : "禁止");
					setTextFill(item ? Color.LAWNGREEN : Color.FIREBRICK);

				}
			}
		}
	}

	class EditingCell extends TableCell<UserGroupProperty, String> {

		private TextField textField;

		public EditingCell() {
		}

		@Override
		public void startEdit() {
			super.startEdit();
			if (isEmpty()) {
				return;
			}

			if (textField == null) {
				createTextField();
			} else {
				textField.setText(getItem());
			}
			setGraphic(textField);
			setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
		}

		@Override
		public void cancelEdit() {
			super.cancelEdit();
			setContentDisplay(ContentDisplay.TEXT_ONLY);
		}

		@Override
		public void updateItem(String item, boolean empty) {
			super.updateItem(item, empty);
			if (!isEmpty()) {
				if (textField != null) {
					textField.setText(item);
				}
				setText(item);
			}
		}

		private void createTextField() {
			textField = new TextField(getItem());
			textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()
					* 2);
			textField.setOnAction(new EventHandler<ActionEvent>() {
				public void handle(ActionEvent event) {
					commitEdit(textField.getText());
				};
			});
		}
	}
}
