javafx макет целевого элемента управления перетаскиванием - PullRequest
0 голосов
/ 07 ноября 2019

Мы пытаемся достичь этого макета, строка кубиков - это TextFields, которые заполняются одной из букв, которые находятся сбоку от кубика при нажатии кнопки Random.
У нас есть Target TextField, который состоит изduh TextFields.
Когда пользователь перетаскивает одну из кубиков в цель, цель заполняется.
Проблема заключается в том, что отношение источника к цели равно 1: 1, и пользователь заранее не знает, гдеисточник должен быть размещен.
Далее мы попытались использовать кнопку для представления кости и перетащить кнопку на новую панель, которая является AnchorPane. Когда мы пытаемся добавить вторую кнопку, мы получаем ошибку при попытке добавить дубликаты дочерних элементов на панель

Вопросы:
1. Можем ли мы иметь отношение один ко многимSource to Targets?
Если да, то как мы это закодируем? Похоже, если это возможно, нереальные строки кода

Как преодолеть проблемы с использованием концепции newPane?

ИЛИ есть лучший способ создать это?
Мы знаем, что можем нажатьButton и создайте слово и добавьте его в ListView, а не то, что нам нужно.

Мы опубликуем код для использования Button на новой панели, она работает, но когда мы продублируемэтот код для второй кнопки мы получаем ошибку, как указано выше

    @Override
public void initialize(URL url, ResourceBundle rb) {

    // Add mouse event handlers for the source
    btnOK.setOnMousePressed((MouseEvent event) -> {
        btnOK.setMouseTransparent(true);
        event.setDragDetect(true);
    });

    btnOK.setOnMouseReleased((MouseEvent event) -> {
        btnOK.setMouseTransparent(false);
    });

    btnOK.setOnMouseDragged((MouseEvent event) -> {
        event.setDragDetect(false);
    });

    btnOK.setOnDragDetected((MouseEvent event) -> {
        btnOK.startFullDrag();
    });

    // Add mouse event handlers for the target
    // =======================================
     newPane.setOnMouseDragEntered((MouseDragEvent event) -> {
    });
    btnOK.setOnMouseDragEntered((MouseDragEvent event) -> {
    });
    newPane.setOnMouseDragOver((MouseDragEvent event) -> {
    });

    newPane.setOnMouseDragReleased((MouseDragEvent event) -> {
    System.out.println(event.getX());
    System.out.println(event.getY());
    double h = event.getX();
    double v = event.getY();
    newPane.getChildren().add(btnOK);
    btnOK.setLayoutX(h);
    btnOK.setLayoutY(v);
        t1.setText(s1.getText());
        t1.setStyle("-fx-background-color: lightblue;");
        //newPane.getChildren().add(s1);
    });
    tosswordPane.setOnMouseDragExited((MouseDragEvent event) -> {
    });
}

Вот снимок экрана макета, который мы пытаемся достичь
enter image description here

Ответы [ 2 ]

1 голос
/ 09 ноября 2019

Оригинальный вопрос, связанный с использованием перетаскивания мышью, чтобы имитировать ручную игру в Toss Word.
Этот метод перетаскивания не очень хорошо работал, так что вот новый метод
Эта игра была продуктом КракДата написания копии игры 1948 года, написана Ади Э. Гиссоу.
Toss Word имеет 14 кубиков, буквы на кубиках следующие:

d1 = "GHDCEI";d2 = "IKLHIG";d3 = "TARSMV";d4 = "EYIUAO";d5 = "SABODY";
d6 = "BACEFD";d7 = "МНКЛИТ";d8 = "LMONIP";d9 = "IEOHRF";d10 = "MEORSN";
d11 = "EAXWYZ";d12 = "МОРЕ";d13 = "UNSHOT";d14 = "PROSTQ";

Правила броска слов
Игроки по очереди бросают кубики и формируют слова из полученных букв. Слова должны иметь как минимум 3 буквы и не иметь собственных имен. Наберите один балл за каждую букву, использованную при составлении слов. Бонус: использование всех 14 букв означает 25, а не 14. Бонус: слово «ИГРА» насчитывает 50 баллов.

Дизайн игры
Мы использовали TextFields для представленияИгральные кости и доска для игры в мишени
Мы используем минимальные символы для именования этих источников (s1) и цели (t1)
Мы использовали события «При нажатии мыши» для имитации размещения буквы «кости» на доске для игры в мишени
Затем мыиспользуется событие «При нажатии мыши», чтобы разрешить удаление буквы «Кости» и разместить ее в новой позиции

. Мы используем логическое значение PLAY = false, чтобы запретить бросание костей после начала игры
Для имитации броскаигральные кости, которые мы используем для генерации случайных чисел, лямбда с одним слоем
. 1032 * БОЛЬШОЙ откат к дизайну Target Playing Board - каждый TextField требует 117 строк кода
Мы уменьшаем нашу Target Playing Board до 10 строкна 8 столбцов, что составляет примерно 9360 строк очень избыточного кода для каждого TextField на игровом поле

Если у кого-то есть лучший дизайн макета для Target Playing Board, не стесняйтесь комментировать!


Одно очень аккуратное объявление CSS-стиля было использовано не моим творением, а найдено на SO
Это предотвращает потерю границы вокруг TextField при применении цветового стиля
Здесьэто t2.setStyle ("- fx-control-inner-background: lightblue")
Мы опубликуем фрагмент кода генератора случайных чисел и выбор Dice
Мы опубликуем полный код для одногоВзаимодействие с игровым столом

Бросание костей

 @FXML
 private void onRandom() throws NoSuchFieldException{
    //new Random().ints(7, 1, 7).forEach(System.out::println);
    makeEnabled();
    if(PLAY == true){
        btnOK.requestFocus();
        return;
    }
    makeVisible();
    new Random().ints(1, 1, 7).forEach(ints -> {
    int V = ints;
    String d1 = "GHDCEI";
    String S1 = String.valueOf(d1.charAt(V-1));
    s1.setText(S1);
    });<br>

Выбор костей

    @Override
public void initialize(URL url, ResourceBundle rb) {

    s1.setOnMouseClicked((MouseEvent )->{
    move = s1.getText();
    s1.setVisible(false);
    PLAY = true;
    });
    s2.setOnMouseClicked((MouseEvent )->{
    move = s2.getText();
    s2.setVisible(false);
    PLAY = true;
    });<br>

Размещение и удаление букв с игрового поля

    @FXML
private void onMC2(){
if(PLAY == false){
    t2.setStyle("-fx-control-inner-background:red");
    return;
}
t2.setText(move);
move = "";
btnOK.requestFocus();
if(t2.getText().isEmpty()){
    t2.setStyle("-fx-control-inner-background:white");
}else{;
    t2.setStyle("-fx-control-inner-background:lightblue");
}
// Code above error traps and places dice on Play Field
// Code below removes the dice to permit moving to alternate target location

t2.setOnMousePressed((MouseEvent event) -> { 
    if(t2.getText().equals(s1.getText())){
        if(!s1.isVisible()){
        s1.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s2.getText())){
        if(!s2.isVisible()){
        s2.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s3.getText())){
        if(!s3.isVisible()){
        s3.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s4.getText())){
        if(!s4.isVisible()){
        s4.setVisible(true);
        t2.setText("");
         return;
        }
    }
    if(t2.getText().equals(s5.getText())){
        if(!s5.isVisible()){
        s5.setVisible(true);
        t2.setText("");
        return; 
        }
    }
    if(t2.getText().equals(s6.getText())){
        if(!s6.isVisible()){
        s6.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s7.getText())){
        if(!s7.isVisible()){
        s7.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s8.getText())){
        if(!s8.isVisible()){
        s8.setVisible(true);
        t2.setText("");
        return;
        }            
    }
    if(t2.getText().equals(s9.getText())){
        if(!s9.isVisible()){
        s9.setVisible(true);
        t2.setText("");
        return;
        }  
    }
    if(t2.getText().equals(s10.getText())){
        if(!s10.isVisible()){
        s10.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s11.getText())){
        if(!s11.isVisible()){
        s11.setVisible(true);
        t2.setText("");
        return;
        } 
    }
    if(t2.getText().equals(s12.getText())){
        if(!s12.isVisible()){
        s12.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s13.getText())){
        if(!s13.isVisible()){
        s13.setVisible(true);
        t2.setText("");
        return;
        }
    }
    if(t2.getText().equals(s14.getText())){
        if(!s14.isVisible()){
        s14.setVisible(true);
        t2.setText("");
        return;
        }   
    }
});
}<br>

Одно время мы рассматривали возможность использования процесса для генерации возможных слов из результатов броскадисе. Вот код, который генерирует поисковые комбинации из броска костей. Затем он запускается против словаря с потоком
Мы не включили это в игру, казалось, что он победил идею игры
, которая должна была ДУМАТЬ

Код для построения поисковых слов

Private Void buildSearchWords(){
   String W = "ILRYADIIEMASHT".toLowerCase();
   int L = W.length();
   ArrayList<String> rearange = new ArrayList<>();
   for(int i = 1; i <= L; i++){

   String firstLetter = W.substring(0, i); 
   String endLetter = W.substring(L - (L-i), L);
   String endLetterNew = W.substring(L-i);

   StringBuilder sb = new StringBuilder(W);
   sb.replace(0, i, endLetterNew);
   sb.replace(L-i, L, firstLetter);

   rearange.add(sb.toString());

   }
    for(int X = 0; X < rearange.size();X++){
        String A = rearange.get(X);
        txaInput.appendText(A);
        txaInput.appendText(" ");
    }  

Код для сравнения со словарем

        List<String> dictionary = Arrays.asList(dictionaryArray);
    ArrayList<String> list = new ArrayList<>();

    int W = txtMonitor.getText().length();

    String newFirstLetter = txtMonitor.getText().substring(0, 1).toLowerCase();

    String newEndLetter = txtMonitor.getText().substring(W - 2, W);
    }

    dictionary.stream().filter(s -> s.startsWith(searchString)
            || s.startsWith(nF, 0)
            && s.length() > 1 && s.length() <= W+3 
            && s.endsWith(nE))
            .forEach(list :: add);
1 голос
/ 08 ноября 2019

Мы можем превратить это в двухэтапный (танцевальный) процесс и сделать его вроде управляемым
Управляемая часть включает в себя сокращение Target TextField до 10 строк на 8 столбцов
Это будет означать, что вам нужно всего лишь 80 раз 6строк кода на кубик с общим количеством 6720 строк кода. НЕ здорово, но это работает, скопируйте и вставьте ваше сердце
ОН в верхней части нашего дикого кода, вы увидите бесполезный метод наведения мыши
Он работает так, удерживая кнопку мыши нажатой, и отпустите над целью
Мы использовали onMouseReleased в целевой области, которую можно использовать onMouseClicked

     @FXML
 private void onHover(){
     t4.setText(s4.getText());
 }

String move;// needs to be global
@Override
public void initialize(URL url, ResourceBundle rb) {

    s6.setOnMouseClicked((MouseEvent e)->{
      move = s6.getText();
      //s6.setVisible(false);
    });

    t1.setOnMouseReleased((MouseEvent event)->{
        if(s6.isVisible()){
        t1.setText(move);
        s6.setVisible(false);
        }
    });

    t2.setOnMouseReleased((MouseEvent e)->{
        if(s6.isVisible()){
        t2.setText(move);
        s6.setVisible(false);
        }
    });

Счастливого копирования и вставки, ха-ха

...