示例#1
0
 @Override
 public void bindBidirectional(Property<ObservableSet<E>> other) {
   try {
     super.bindBidirectional(other);
   } catch (IllegalArgumentException e) {
     if ("Cannot bind property to itself".equals(e.getMessage()) && this != other) {
       // XXX: The super implementation relies on equals() not on
       // object identity to infer whether a binding is valid. It thus
       // throw an IllegalArgumentException if two equal properties are
       // passed in, even if they are not identical. We have to
       // ensure they are thus unequal to establish the binding; as
       // our value will be initially overwritten anyway, we may adjust
       // the local value; to reduce noise, we only adjust the local
       // value if necessary
       if (other.getValue() == null) {
         if (getValue() == null) {
           // set to value != null
           setValue(FXCollections.observableSet(new HashSet<E>()));
         }
       } else {
         if (getValue().equals(other)) {
           // set to null value
           setValue(null);
         }
       }
       // try again
       super.bindBidirectional(other);
     } else {
       throw (e);
     }
   }
 }
示例#2
0
 @Override
 public void unbindBidirectional(Property<ObservableSet<E>> other) {
   try {
     super.unbindBidirectional(other);
   } catch (IllegalArgumentException e) {
     if ("Cannot bind property to itself".equals(e.getMessage()) && this != other) {
       // XXX: The super implementation relies on equals() not on
       // object identity to infer whether a binding is valid. It thus
       // throw an IllegalArgumentException if two equal properties are
       // passed in, even if they are not identical. We have to
       // ensure they are thus unequal to remove the binding; we
       // have to restore the current value afterwards.
       ObservableSet<E> oldValue = getValue();
       if (other.getValue() == null) {
         // set to value != null
         setValue(FXCollections.observableSet(new HashSet<E>()));
       } else {
         // set to null value
         setValue(null);
       }
       // try again
       super.unbindBidirectional(other);
       setValue(oldValue);
     } else {
       throw (e);
     }
   }
 }
示例#3
0
  protected Market(GoodType goodType) {
    this.goodType = goodType;
    // if the market is a labor market, buyers hire and sellers get hired. Otherwise buyers receive
    // and sellers earn
    if (goodType.isLabor()) policy = new SimpleHiringTradePolicy();
    else policy = SimpleGoodTradePolicy.getInstance();

    buyers = FXCollections.observableSet(new HashSet<>());
    sellers = FXCollections.observableSet(new HashSet<>());
    marketData = new MarketData();

    // build the gui inspector
    if (MacroII.hasGUI()) {

      marketInspector = buildInspector();
    }
  }
/**
 * AbstractDisableable.
 *
 * <p>Binds {@code disabled} to {@code disablers.emptyProperty().not()}.
 *
 * <p>If a subclass wants to bind {@code disabled} to additional reasons, it must unbind {@code
 * disabled} first.
 *
 * @author Werner Randelshofer
 * @version $Id$
 */
public class AbstractDisableable implements Disableable {
  protected final ReadOnlyBooleanWrapper disabled = new ReadOnlyBooleanWrapper();
  protected final SetProperty<Object> disablers =
      new SimpleSetProperty<Object>(FXCollections.observableSet());

  public AbstractDisableable() {
    disabled.bind(disablers.emptyProperty().not());
  }

  @Override
  public ReadOnlyBooleanProperty disabledProperty() {
    return disabled.getReadOnlyProperty();
  }

  @Override
  public SetProperty<Object> disablersProperty() {
    return disablers;
  }
}
  /**
   * Event handler of OK button.
   *
   * @param event ActionEvent of this event.
   */
  @FXML
  private void onOkClick(ActionEvent event) {
    int startIdx = startCombo.getSelectionModel().getSelectedIndex();
    int endIdx = endCombo.getSelectionModel().getSelectedIndex();
    currentTarget.set(
        FXCollections.observableArrayList(startCombo.getItems().subList(startIdx, endIdx + 1)));
    currentClassNameSet.set(FXCollections.observableSet());
    summaryData.set(new SummaryData(currentTarget.get()));

    Task<Void> topNTask = histogramController.getDrawTopNDataTask(currentTarget.get(), true, null);
    super.bindTask(topNTask);
    Thread topNThread = new Thread(topNTask);
    topNThread.start();

    Task<Void> summarizeTask =
        summaryController.getCalculateGCSummaryTask(this::drawRebootSuspectLine);
    super.bindTask(summarizeTask);
    Thread summarizeThread = new Thread(summarizeTask);
    summarizeThread.start();
  }
 @Test
 public void mirroredSet() throws Exception {
   ObservableSet<String> source = FXCollections.observableSet();
   source.add("alpha");
   source.add("beta");
   ObservableSet<String> dest = ObservableMirrors.mirrorSet(source, gate);
   assertEquals(0, gate.getTaskQueueSize());
   assertEquals(2, dest.size());
   source.add("delta");
   assertEquals(1, gate.getTaskQueueSize());
   assertEquals(2, dest.size());
   gate.waitAndRun();
   assertEquals(0, gate.getTaskQueueSize());
   assertEquals(3, dest.size());
   source.removeAll(ImmutableList.of("alpha", "beta"));
   assertEquals(2, gate.getTaskQueueSize());
   gate.waitAndRun();
   gate.waitAndRun();
   assertEquals(1, dest.size());
   assertTrue(dest.contains("delta"));
 }
@IDProperty("id")
@DefaultProperty("children")
public class Widget {
  private StringProperty id = new SimpleStringProperty();
  private StringProperty name = new SimpleStringProperty();
  private IntegerProperty number = new SimpleIntegerProperty();
  private ObservableList<Widget> children = FXCollections.observableArrayList();
  private ObservableSet<String> set = FXCollections.observableSet();
  private ObservableMap<String, Object> properties = FXCollections.observableHashMap();
  private BooleanProperty enabledProperty = new SimpleBooleanProperty(true);
  private ArrayList<String> styles = new ArrayList<String>();
  private ArrayList<String> values = new ArrayList<String>();
  private float[] ratios = new float[] {};
  private String[] names = new String[] {};

  public static final String ALIGNMENT_KEY = "alignment";
  public static final int TEN = 10;
  private EventHandler<ActionEvent> actionHandler;

  public Widget() {
    this(null);
  }

  public Widget(String name) {
    setName(name);
  }

  public String getId() {
    return id.get();
  }

  public void setId(String value) {
    id.set(value);
  }

  public StringProperty idProperty() {
    return id;
  }

  public String getName() {
    return name.get();
  }

  public void setName(String value) {
    name.set(value);
  }

  public StringProperty nameProperty() {
    return name;
  }

  public int getNumber() {
    return number.get();
  }

  public void setNumber(int value) {
    number.set(value);
  }

  public IntegerProperty numberProperty() {
    return number;
  }

  public ObservableList<Widget> getChildren() {
    return children;
  }

  public ObservableMap<String, Object> getProperties() {
    return properties;
  }

  public boolean isEnabled() {
    return enabledProperty.get();
  }

  public void setEnabled(boolean value) {
    enabledProperty.set(value);
  }

  public BooleanProperty enabledProperty() {
    return enabledProperty;
  }

  public List<String> getStyles() {
    return styles;
  }

  public List<String> getValues() {
    return values;
  }

  public void setValues(List<String> values) {
    if (values == null) {
      throw new IllegalArgumentException();
    }

    this.values = new ArrayList<String>();
    this.values.addAll(values);
  }

  public float[] getRatios() {
    return Arrays.copyOf(ratios, ratios.length);
  }

  public void setRatios(float[] ratios) {
    this.ratios = Arrays.copyOf(ratios, ratios.length);
  }

  public String[] getNames() {
    return Arrays.copyOf(names, names.length);
  }

  public void setNames(String[] names) {
    this.names = Arrays.copyOf(names, names.length);
  }

  public ObservableSet<String> getSet() {
    return set;
  }

  public static Alignment getAlignment(Widget widget) {
    return (Alignment) widget.getProperties().get(ALIGNMENT_KEY);
  }

  public static void setAlignment(Widget widget, Alignment alignment) {
    widget.getProperties().put(ALIGNMENT_KEY, alignment);
  }

  public final void setOnAction(EventHandler<ActionEvent> value) {
    actionHandler = value;
  }

  public final EventHandler<ActionEvent> getOnAction() {
    return actionHandler;
  }

  public final void fire() {
    actionHandler.handle(new ActionEvent());
  }
}
示例#8
0
public class FileTreePane extends BorderPane {

  private static final Logger logger = LoggerFactory.getLogger(FileTreePane.class);

  // TODO make use of the useCase => store and retrieve the last selection per use-case!
  private final StringProperty useCaseProperty =
      new SimpleStringProperty(this, "useCase", "default") {
        @Override
        public void set(final String useCase) {
          assertNotNull("useCase", useCase);
        }
      };

  @FXML private TreeTableView<FileTreeItem<?>> treeTableView;

  @FXML private CheckBox showHiddenFilesCheckBox;

  @FXML private Button refreshButton;

  @FXML private Button createDirButton;

  @FXML private Button renameButton;

  @FXML private Button deleteButton;

  @FXML private TreeTableColumn<FileTreeItem<?>, String> nameTreeTableColumn;

  @FXML private TreeTableColumn<FileTreeItem<?>, String> sizeTreeTableColumn;

  @FXML private TreeTableColumn<FileTreeItem<?>, String> lastModifiedTreeTableColumn;

  private final BooleanProperty showHiddenFilesProperty =
      new SimpleBooleanProperty(this, "showHiddenFiles", false);

  private FileTreeItem<?> rootFileTreeItem;

  private final ObservableSet<File> selectedFiles =
      FXCollections.observableSet(new HashSet<File>());

  private final ObjectProperty<FileFilter> fileFilterProperty =
      new SimpleObjectProperty<FileFilter>(this, "fileFilter") {
        @Override
        public void set(FileFilter newValue) {
          // WORKAROUND: the selection is modified when setting the fileFilter from the outside
          // (refreshing the children seems to cause it) :-(

          if (updatingSelectedFiles) {
            super.set(newValue);
            return;
          }

          updatingSelectedFiles = true;
          try {
            super.set(newValue);
            treeTableView.getSelectionModel().clearSelection();
          } finally {
            updatingSelectedFiles = false;
          }

          for (File f : selectedFiles) selectFileTreeItemForSelectedFile(f);
        }
      };

  private final SetChangeListener<File> selectedFilesChangeListener =
      new SetChangeListener<File>() {
        @Override
        public void onChanged(final SetChangeListener.Change<? extends File> c) {
          assertFxApplicationThread();

          if (c.getElementRemoved() != null)
            unselectTreeItemForUnselectedFile(c.getElementRemoved());

          if (c.getElementAdded() != null) selectFileTreeItemForSelectedFile(c.getElementAdded());

          updateDisable();
        }
      };

  private boolean updatingSelectedFiles;

  private final CopyOnWriteArrayList<WeakReference<RefreshListener>> refreshListeners =
      new CopyOnWriteArrayList<>();
  private final ReferenceQueue<RefreshListener> refreshListenersReferenceQueue =
      new ReferenceQueue<>();

  public FileTreePane() {
    loadDynamicComponentFxml(FileTreePane.class, this);
    rootFileTreeItem = new RootFileTreeItem(this);

    // The root here is *not* the real root of the file system and should be hidden, because
    // (1) we might want to have 'virtual' visible roots like "Home", "Desktop", "Drives" and
    // (2) even if we displayed only the real file system without any shortcuts like "Desktop",
    // we'd still have multiple roots on a crappy pseudo-OS like Windows still having these shitty
    // drive letters.
    treeTableView.setShowRoot(false);
    treeTableView.setRoot(rootFileTreeItem);
    treeTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
    treeTableView
        .getSelectionModel()
        .selectedItemProperty()
        .addListener(
            (ChangeListener<TreeItem<FileTreeItem<?>>>)
                (observable, o, n) -> updateSelectedFiles());
    treeTableView
        .getSelectionModel()
        .getSelectedItems()
        .addListener((InvalidationListener) observable -> updateSelectedFiles());

    selectedFiles.addListener(selectedFilesChangeListener);
    showHiddenFilesCheckBox.selectedProperty().bindBidirectional(showHiddenFilesProperty);

    // TODO remove the following line - preferably replace by proper, use-case-dependent management!
    selectedFiles.add(IOUtil.getUserHome());
    updateDisable();
  }

  private void updateDisable() {
    final int seletectItemsSize = treeTableView.getSelectionModel().getSelectedItems().size();
    createDirButton.setDisable(
        seletectItemsSize != 1); // the selection is the parent - and thus required!
    renameButton.setDisable(seletectItemsSize != 1);
    deleteButton.setDisable(seletectItemsSize < 1);
  }

  public boolean isRefreshButtonVisible() {
    return refreshButton.isVisible();
  }

  public void setRefreshButtonVisible(boolean visible) {
    refreshButton.setVisible(visible);
  }

  private void updateSelectedFiles() {
    assertFxApplicationThread();

    if (updatingSelectedFiles) return;

    updatingSelectedFiles = true;
    try {
      final ObservableList<TreeItem<FileTreeItem<?>>> selectedItems =
          treeTableView.getSelectionModel().getSelectedItems();
      final Set<File> newSelectedFiles = new HashSet<File>(selectedItems.size());
      for (final TreeItem<FileTreeItem<?>> selectedItem : selectedItems) {
        final FileTreeItem<?> fileTreeItem =
            selectedItem == null
                ? null
                : selectedItem.getValue(); // strange but true: it can be null
        if (fileTreeItem instanceof FileFileTreeItem)
          newSelectedFiles.add(((FileFileTreeItem) fileTreeItem).getFile());
      }
      selectedFiles.retainAll(newSelectedFiles);
      selectedFiles.addAll(newSelectedFiles);
    } finally {
      updatingSelectedFiles = false;
    }
  }

  private void selectFileTreeItemForSelectedFile(final File file) {
    if (updatingSelectedFiles) return;

    updatingSelectedFiles = true;
    try {
      final FileTreeItem<?> fileTreeItem = rootFileTreeItem.findFirst(file);
      if (fileTreeItem == null) {
        IllegalStateException x =
            new IllegalStateException("File does not have corresponding FileTreeItem: " + file);
        logger.warn("selectFileTreeItemForSelectedFile: " + x, x);
      } else {
        TreeItem<?> ti = fileTreeItem.getParent();
        while (ti != null) {
          ti.setExpanded(true);
          ti = ti.getParent();
        }

        // TODO maybe, instead of scrolling here (after each single item is selected), immediately,
        // we should wait (=> Timer) and scroll to the *first* selection, later?!
        treeTableView.getSelectionModel().select(fileTreeItem);
        int row = treeTableView.getRow(fileTreeItem);
        if (row >= 0) treeTableView.scrollTo(row);
      }
    } finally {
      updatingSelectedFiles = false;
    }
  }

  private void unselectTreeItemForUnselectedFile(final File file) {
    if (updatingSelectedFiles) return;

    updatingSelectedFiles = true;
    try {
      final FileTreeItem<?> fileTreeItem = rootFileTreeItem.findFirst(file);
      if (fileTreeItem != null) {
        final Set<TreeItem<FileTreeItem<?>>> selectedItems =
            new LinkedHashSet<TreeItem<FileTreeItem<?>>>(
                treeTableView.getSelectionModel().getSelectedItems());
        if (selectedItems.remove(fileTreeItem)) {
          treeTableView.getSelectionModel().clearSelection();
          for (TreeItem<FileTreeItem<?>> treeItem : selectedItems)
            treeTableView.getSelectionModel().select(treeItem);
        }
      }
    } finally {
      updatingSelectedFiles = false;
    }
  }

  public ObservableSet<File> getSelectedFiles() {
    return selectedFiles;
  }

  public void refresh() {
    fireRefreshEvent();
  }

  private void fireRefreshEvent() {
    final RefreshEvent event = new RefreshEvent(this);
    expungeRefreshListeners();
    for (final Reference<RefreshListener> reference : refreshListeners) {
      final RefreshListener listener = reference.get();
      if (listener != null) listener.onRefresh(event);
    }
  }

  protected void addRefreshListener(RefreshListener listener) {
    expungeRefreshListeners();
    refreshListeners.add(
        new IdentityWeakReference<RefreshListener>(
            assertNotNull("listener", listener), refreshListenersReferenceQueue));
  }

  protected void removeRefreshListener(RefreshListener listener) {
    expungeRefreshListeners();
    refreshListeners.remove(
        new IdentityWeakReference<RefreshListener>(assertNotNull("listener", listener)));
  }

  private void expungeRefreshListeners() {
    Reference<? extends RefreshListener> ref;
    while ((ref = refreshListenersReferenceQueue.poll()) != null) refreshListeners.remove(ref);
  }

  public SelectionMode getSelectionMode() {
    return treeTableView.getSelectionModel().getSelectionMode();
  }

  public void setSelectionMode(SelectionMode selectionMode) {
    assertNotNull("selectionMode", selectionMode);
    treeTableView.getSelectionModel().setSelectionMode(selectionMode);
  }

  protected TreeTableView<FileTreeItem<?>> getTreeTableView() {
    return treeTableView;
  }

  public FileTreeItem<?> getRootFileTreeItem() {
    return rootFileTreeItem;
  }

  public void setRootFileTreeItem(FileTreeItem<?> rootFileTreeItem) {
    this.rootFileTreeItem = rootFileTreeItem;
    treeTableView.setRoot(rootFileTreeItem);
  }

  public BooleanProperty showHiddenFilesProperty() {
    return showHiddenFilesProperty;
  }

  public ObjectProperty<FileFilter> fileFilterProperty() {
    return fileFilterProperty;
  }

  /**
   * Gets the use-case.
   *
   * @return the use-case. Never <code>null</code>.
   * @see #useCaseProperty()
   */
  public String getUseCase() {
    return useCaseProperty.get();
  }
  /**
   * Sets the use-case.
   *
   * @param useCase the use-case. Must not be <code>null</code>.
   * @see #useCaseProperty()
   */
  public void setUseCase(String useCase) {
    useCaseProperty.set(useCase);
  }
  /**
   * The use-case-property. This identifier is used to remember the last selection.
   *
   * @return the use-case-property. Never <code>null</code>.
   */
  public StringProperty useCaseProperty() {
    return useCaseProperty;
  }

  @Override
  public void requestFocus() {
    super.requestFocus();
    treeTableView.requestFocus();
  }

  @FXML
  private void refreshButtonClicked(final ActionEvent event) {
    fireRefreshEvent();
    treeTableView.refresh();
  }

  @FXML
  private void createDirButtonClicked(final ActionEvent event) {
    final File parent = assertNotNull("getSelectedDirectory()", getSelectedDirectory());

    final String dirName =
        showCreateOrRenameDialog(
            "Create folder",
            "What should be the new folder's name?",
            parent,
            null,
            (name) -> !createFile(parent, name).exists());

    if (dirName != null) {
      final File directory = createFile(parent, dirName);
      directory.mkdirs();
      if (!directory.isDirectory())
        showErrorDialog(
            "Failed to create directory!",
            "The directory could not be created! Maybe you're missing the required permissions?!");
      else {
        refresh();
        getSelectedFiles().clear();
        getSelectedFiles().add(directory);
      }
    }
  }

  @FXML
  private void renameButtonClicked(final ActionEvent event) {
    final File selectedFile = getSelectedFile();
    final File parent = selectedFile.getParentFile();

    final String newName =
        showCreateOrRenameDialog(
            "Rename",
            "What should be the new name?",
            parent,
            selectedFile.getName(),
            (name) -> !selectedFile.getName().equals(name) && !createFile(parent, name).exists());

    if (newName != null) {
      final File newFile = createFile(parent, newName);
      if (!selectedFile.renameTo(newFile))
        showErrorDialog(
            "Failed to rename file!",
            "The file could not be renamed! Maybe you're missing the required permissions?!");
      else {
        refresh();
        getSelectedFiles().clear();
        getSelectedFiles().add(newFile);
      }
    }
  }

  @FXML
  private void deleteButtonClicked(final ActionEvent event) {
    final Set<File> selectedFiles = getSelectedFiles();
    if (selectedFiles.isEmpty()) return;

    Alert alert = new Alert(AlertType.CONFIRMATION);
    alert.setTitle("Delete");
    alert.setHeaderText("Delete these files?");

    final VBox contentContainer = new VBox();
    contentContainer.setSpacing(8);

    final Text contentText =
        new Text("The following files and folders are about to be deleted (folders recursively!):");
    contentText.setWrappingWidth(400);
    contentContainer.getChildren().add(contentText);

    final ListView<String> fileListView = new ListView<>();
    for (final File file : selectedFiles) fileListView.getItems().add(file.getAbsolutePath());

    fileListView.setPrefSize(400, 200);
    contentContainer.getChildren().add(fileListView);

    alert.getDialogPane().setContent(contentContainer);

    if (alert.showAndWait().get() == ButtonType.OK) {
      final List<File> notDeletedFiles = new ArrayList<>();
      for (final File file : selectedFiles) {
        file.deleteRecursively();
        if (file.exists()) notDeletedFiles.add(file);
      }
      refresh();

      if (!notDeletedFiles.isEmpty())
        showErrorDialog(
            "Deleting failed!",
            "The selected files (or directories) could be not deleted. They may have been deleted partially, though.");
    }
  }

  private String showCreateOrRenameDialog(
      final String title,
      final String headerText,
      final File parent,
      final String name,
      final NameVerifier nameVerifier) {
    final Alert alert = new Alert(AlertType.CONFIRMATION);
    alert.setTitle(title);
    alert.setHeaderText(headerText);

    final GridPane contentContainer = new GridPane();
    contentContainer.setPadding(new Insets(8));
    contentContainer.setHgap(8);
    contentContainer.setVgap(8);

    contentContainer.add(new Label("Parent:"), 0, 0);
    final TextField parentTextField = new TextField();
    parentTextField.setEditable(false);

    parentTextField.setText(parent.getAbsolutePath());
    contentContainer.add(parentTextField, 1, 0);

    contentContainer.add(new Label("Name:"), 0, 1);

    final TextField dirNameTextField = new TextField();
    dirNameTextField.setText(name);
    GridPane.setHgrow(dirNameTextField, Priority.ALWAYS);
    contentContainer.add(dirNameTextField, 1, 1);

    final InvalidationListener updateDisableInvalidationListener =
        (observable) -> {
          final String dirName = dirNameTextField.getText();
          final Node okButton = alert.getDialogPane().lookupButton(ButtonType.OK);
          if (isEmpty(dirName)) okButton.setDisable(true);
          else {
            final boolean nameAcceptable = nameVerifier.isNameAcceptable(dirName);
            okButton.setDisable(!nameAcceptable);
          }
        };
    dirNameTextField.textProperty().addListener(updateDisableInvalidationListener);

    alert.getDialogPane().setContent(contentContainer);
    alert.setOnShowing(
        (event) -> {
          dirNameTextField.requestFocus();
          dirNameTextField.selectAll();
          updateDisableInvalidationListener.invalidated(null);
        });

    if (alert.showAndWait().get() == ButtonType.OK) return dirNameTextField.getText();
    else return null;
  }

  private void showErrorDialog(final String headerText, final String contentText) {
    final Alert alert = new Alert(AlertType.ERROR);
    //		alert.setTitle("Error");
    alert.setHeaderText(headerText);
    alert.setContentText(contentText);
    alert.showAndWait();
  }

  @FunctionalInterface
  private static interface NameVerifier {
    boolean isNameAcceptable(String name);
  }

  private File getSelectedFile() {
    final Iterator<File> iterator = getSelectedFiles().iterator();
    if (!iterator.hasNext()) return null; // nothing selected

    final File file = iterator.next();

    if (iterator.hasNext()) return null; // more than one selected.
    else return file;
  }

  private File getSelectedDirectory() {
    File directory = getSelectedFile();

    if (directory != null && !directory.isDirectory()) directory = directory.getParentFile();

    return directory;
  }

  protected TreeTableColumn<FileTreeItem<?>, String> getNameTreeTableColumn() {
    return nameTreeTableColumn;
  }

  protected TreeTableColumn<FileTreeItem<?>, String> getSizeTreeTableColumn() {
    return sizeTreeTableColumn;
  }

  protected TreeTableColumn<FileTreeItem<?>, String> getLastModifiedTreeTableColumn() {
    return lastModifiedTreeTableColumn;
  }
}