Постановка задачи: На рабочей панели графического редактора выбрать фигуру и путем перетаскивания изменить ее положение (переместить ее на панели), реализовать выбор и перетаскивание нескольких фигур.
Набор фигур для запуска приложения
Перетаскивание состоит:
Шаг 1. Выбор фигуры по щелчку мыши (н-р, событие MouseEvent.MOUSE_PRESSED).
Шаг 2. Выделение фигуры (изменение свойств фигуры и сохранение текущих).
Шаг 3. Изменение положения фигуры и возвращение фигуры к прежнему виду.
Необходимо организовать временное хранение состояния фигуры -
используется для восстановления состояния объекта до предыдущего состояния.
Memento (снимок) – хранитель, сохраняет состояние объекта Originator;
Originator (текущий объект) – создает экземпляр объекта хранителя. Имеет полный доступ к Memento.
Caretaker («опекун») – производит сохранения множества состояний Memento в стеке для извелчения в порядке сохранения.
Определите свойства фигуры, которые будут изменены при выделении и инкапсулируйте их в класс Memento для сохранения текущего состояния:
public class Momento {
private Shape snape;
private double width;
private Color color;
//сделать снимок
public Momento(Shape state){
this.snape = state;
width= snape.getStrokeWidth();
color= (Color) snape.getStroke();
}
//вернуть первоначальный свойства
public Shape getState(){
snape.setStrokeWidth(width);
snape.setStroke(color);
return snape;
}
Создайте Controller для макета Графического редактора, включая панель для рисования, панель подложки и панель инструментов. Инициализируете стартовый набор фигур на панели рисования, загрузку подложки
На каждую фигуру добавить обработчик события
a.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
// создать объект Снимок
temp=new Momento(a);
});
Для визуального выделения выбранной фигуры добавить метод задания константных свойств фигуры, например в класс Memento
public Shape initState(){
snape.setStrokeWidth(2);
snape.setStroke(Color.RED);
return snape;
Объявите и реализуйте обработчики событий мыши. Так как механизм перетаскивания задействует несколько обработчиков событий, то использовать переменную temp для хранения предшествующего состояния в частности восстановления свойств фигуру после ее выделения
public void onBegin(MouseEvent mouseEvent) {//захват
temp.initState().toFront();
}
public void onDrag(MouseEvent mouseEvent) {//движение
if(temp==null) return;
temp.initState().relocate(mouseEvent.getX(), mouseEvent.getY());
}
public void onEnd(MouseEvent mouseEvent) {
if(temp==null) return;
// переместить фигуру из Хранителя
temp.getState().relocate(mouseEvent.getX(), mouseEvent.getY());
temp=null;//использовать и как флаг
}
Создайте класс CareTaker работы со множеством фигур (состояний)
public class MemoSelect {
private Queue<Momento> mementoList = new ArrayDeque<Momento>();
public void push(Momento state){
mementoList.add(state);
}
public Momento poll(){
return mementoList.poll();
}
Объявите и реализуйте обработчики событий мыши для реализации сценария выделения нескольких графических объектов для их последующего перемещения