Javafx конфликтует между наблюдателями и слушателем getstyleclass () - PullRequest
0 голосов
/ 18 ноября 2018

У меня проблема с приложением JavaFX.

У меня есть класс, создающий список кнопок в hbox.Этот класс расширяет AnchorPane.

Когда я нажимаю на кнопку, я изменяю класс css, примененный к этой кнопке, и предыдущий, так что это снова нормально.Проблема в том, чтобы добавить наблюдателя, чтобы моя кнопка была полезной.

Поскольку мой класс уже расширяет AnchorPane, я не могу расширять Observable, поэтому я создал новый класс со статическими методами.Этот класс является наблюдаемым и уведомляет наблюдаемое при вызове метода.

Вот код класса со списком кнопок:

/**
 *
 * @author olivier
 */
public class SpecificElementViewController extends AnchorPane implements Initializable {

  private List<String> elementTypesList;

  @FXML
  private HBox hbox;

  private Button selectedButton = null;

  private SpecificElementListTypes specificElementType;

  public SpecificElementViewController() {
  }

  @Override
  public void initialize(URL location, ResourceBundle resources) {
    hbox.setAlignment(Pos.CENTER);
  }

  public List<String> getElementTypes() {
    return elementTypesList;
  }

  public void setElementTypes(List<String> elementTypesList, SpecificElementListTypes type) {
    this.specificElementType = type;
    Button button;

    if (elementTypesList != null && !elementTypesList.isEmpty()) {

      for (String s : elementTypesList) {
        button = new Button(s);

        button.setOnAction(new EventHandler<ActionEvent>() {
          @Override
          public void handle(ActionEvent event) {
            System.out.println("Pressed button : " + ((Button) event.getSource()).getText());
            if (selectedButton.getStyleClass().contains("selectedNode")) {
              selectedButton.getStyleClass().remove("selectedNode");
            }
            selectedButton = (Button) event.getSource();
            selectedButton.getStyleClass().add("selectedNode");
            SpecificElementViewObservable.handleSpecificElementListClick(specificElementType, selectedButton);
          }
        });
        hbox.getChildren().add(button);
      }
      if (selectedButton == null) {
        selectedButton = (Button) hbox.getChildren().get(0);
        selectedButton.getStyleClass().add("selectedNode");
      }
    }
  }

Вот класс классаНаблюдаемый класс:

public class SpecificElementViewObservable extends Observable {

  private static SpecificElementViewObservable instance;

  public static void handleSpecificElementListClick(SpecificElementListTypes elementType, Button button) {
    SpecificElementViewObservable.getInstance().setChanged();
    SpecificElementViewObservable.getInstance().notifyObservers(new SpecificElementEvent(elementType, button));
  }

  public static SpecificElementViewObservable getInstance() {
    if (instance == null) {
      instance = new SpecificElementViewObservable();
    }
    return instance;
  }
}

Класс, наблюдающий этот класс, слишком велик, чтобы его можно было добавить здесь. Я просто добавлю addobserver и метод обновления:

/**
 *
 * @author olivier
 */
public class MainWindowController extends AnchorPane implements Initializable, Observer {

   @Override
  public void initialize(URL location, ResourceBundle resources) {
     SpecificElementViewObservable.getInstance().addObserver(this);
  }

public void update(Observable o, Object arg) {
        System.out.println("Receive update");
        if (arg instanceof SpecificElementEvent) {
          SpecificElementEvent event = (SpecificElementEvent) arg;
          System.out.println("Type : " + event.getType().toString());
          System.out.println("Button text : " + event.getButton().getText());
          try {
            handlePlanetMenuClick(null);
          } catch (Exception ex) {
            System.out.println("Error using null mouseEvent : " + ex.getMessage());
          }
        } else {
          System.out.println("Error unknown event");
        }
      }

Эта проблема - я могузаставить моего слушателя работать с обновлением css.С этим кодом мой слушатель работает, но CSS не применяется.Как вы можете видеть в методе setElementTypes, список кнопок создается, причем первая из них считается «выбранной».В этот момент применяется CSS (кнопки желтые, кроме кнопки selectedB, которая красная).Когда я нажимаю на другую кнопку, красная снова становится желтой, но новая selectedButton остается желтой (значение selectedButton изменяется).После этого CSS никогда не меняется.

Если я уберу эту строку:

SpecificElementViewObservable.handleSpecificElementListClick(specificElementType, selectedButton);

или эти строки:

SpecificElementViewObservable.getInstance().setChanged();
SpecificElementViewObservable.getInstance().notifyObservers(new SpecificElementEvent(elementType, button));

или переключим

SpecificElementViewObservable.getInstance().notifyObservers(new SpecificElementEvent(elementType, button));

to:

SpecificElementViewObservable.getInstance().notifyObservers();

Затем каждый раз, когда мой слушатель не работает (что нормально), но css работает снова.

Я также пытался удалить условие изметод обновления, поэтому я могу использовать notifyObservers () без параметров.Еще раз, мой слушатель работает, но не CSS.

Знаете ли вы, в чем проблема?

1 Ответ

0 голосов
/ 19 ноября 2018

Я заменил свои кнопки на кнопки-переключатели и ToggleGroup. Я до сих пор не знаю, в чем проблема, но с этим легче справиться, и это работает. Я думаю, что проблема возникла из-за ошибки из-за необходимости обрабатывать выбранную кнопку самостоятельно и была исправлена ​​с помощью методов setSelected () и isSelected toggleButtons.

...