Измените значки предварительного просмотра перетаскиваемых файлов, если источником является файловая система ОС или другJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Измените значки предварительного просмотра перетаскиваемых файлов, если источником является файловая система ОС или друг

Сообщение Anonymous »

Введение
При перетаскивании элементов из другого приложения в DnD Узел в JavaFX Операционная система или исходное приложение обрабатывают визуальное отображение перетаскиваемых элементов, поскольку они являются источником перетаскиваемых файлов.
Это относится и к этому приложению: пользователь имеет возможность перетаскивать определенные категории файлов, и эти файлы принимаются только в зависимости от их расширений (, .jpeg и т. д. для изображений).
Код
Интерфейс DragAndDropBehavior имеет единственный метод handleDroppedFiles(List files), который будет обрабатывать файлы после их удаления.

Код: Выделить всё

import java.io.File;
import java.util.List;

public interface DragAndDropBehavior {
void handleDroppedFiles(List files);
}
Класс BaseDropController реализует DragAndDropBehavior. Его метод hasAllowedExtension(File f, String... Extensions) возвращает true, только если расширение файла соответствует одному из указанных расширений. Метод notifyError(String message) выводит сообщение об ошибке в случае возникновения проблемы.

Код: Выделить всё

import java.io.File;

public abstract class BaseDropController implements DragAndDropBehavior {
protected boolean hasAllowedExtension(File f, String... extensions) {
var name = f.getName().toLowerCase();
for (var ext : extensions)
if (name.endsWith(ext))
return true;

return false;
}
protected void notifyError(String message) {
System.err.println(message);
}
}
ImageDropController расширяет BaseDropController, реализуя таким образом метод handleDroppedFiles(List files) из интерфейса DragAndDropBehavior. handleDroppedFiles — это просто обработчик, используемый при удалении файлов.

Код: Выделить всё

import java.io.File;
import java.util.List;

public class ImageDropController extends BaseDropController {
@Override
public void handleDroppedFiles(List files) {
var image = files.stream().filter(f -> hasAllowedExtension(f, ".png", ".jpg", ".jpeg", ".webp")).findFirst();
image.ifPresentOrElse(
file -> {
System.out.println("Dropped file: " + file.getAbsoluteFile());
},
() -> notifyError("No image file found.")
);
}
}
DragAndDropPane расширяет StackPane. Он представляет собой область, куда следует перетаскивать файлы. ObjectProperty AcceptedExtensions и ObjectProperty onFilesDropped указывают принятые расширения и обработчик файлов при их удалении. Оба будут установлены соответствующим установщиком в зависимости от типа файлов, которые следует перетаскивать.

Код: Выделить всё

import javafx.beans.property.*;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.StackPane;

import java.io.File;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;

public final class DragAndDropPane extends StackPane {
private final ObjectProperty acceptedExtensions = new SimpleObjectProperty();
private final ObjectProperty onFilesDropped = new SimpleObjectProperty();
private final BooleanProperty highlight = new SimpleBooleanProperty(false);

public DragAndDropPane() {
getStyleClass().add("drop-pane");

var label = new Label("Drop files here");
setAlignment(label, Pos.CENTER);
getChildren().add(label);

setOnDragOver(e -> {
if (e.getGestureSource() != this && e.getDragboard().hasFiles()) {
if (acceptsAny(e.getDragboard().getFiles())) {
e.acceptTransferModes(TransferMode.MOVE);
highlight.set(true);
}
}
e.consume();
});

setOnDragExited(e -> {
highlight.set(false);
e.consume();
});

setOnDragDropped(e -> {
var dragBoard = e.getDragboard();
boolean success = false;
if (dragBoard.hasFiles() && acceptsAny(dragBoard.getFiles())) {
var handler = getOnFilesDropped();
if (handler != null)
handler.accept(dragBoard.getFiles());
success = true;
}
e.setDropCompleted(success);
e.consume();
});

highlight.addListener((_, _, hi) ->
pseudoClassStateChanged(javafx.css.PseudoClass.getPseudoClass("active"), hi));
}

private boolean acceptsAny(List files) {
var extensions = getAcceptedExtensions();
if (extensions == null || extensions.isEmpty())
return true;
return files.stream().anyMatch(file ->
extensions.stream().anyMatch(extension -> file.getName().toLowerCase().endsWith(extension.toLowerCase()))
);
}

public void setAcceptedExtensions(Set extensions) {
acceptedExtensions.set(extensions);
}

public void setOnFilesDropped(Consumer c) {
onFilesDropped.set(c);
}

public Set getAcceptedExtensions() {
return acceptedExtensions.get();
}

public ObjectProperty acceptedExtensionsProperty() {
return acceptedExtensions;
}

public Consumer getOnFilesDropped() {
return onFilesDropped.get();
}

public ObjectProperty onFilesDroppedProperty() {
return onFilesDropped;
}
}
ImageDropView просто содержит область перетаскивания и раздел предварительного просмотра для перетаскиваемых файлов. Он загружает соответствующий файл FXML (

Код: Выделить всё

ImageDropView
в данном случае) и привязывает элементы к своим полям. Затем он использует ImageDropController для установки обработчика, когда файлы перетаскиваются в DragAndDropPane с помощью drop.setOnFilesDropped(controller::handleDroppedFiles).

Код: Выделить всё

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.layout.StackPane;

import java.io.IOException;
import java.util.Set;

public final class ImageDropView {
private final Parent root;
@FXML
private DragAndDropPane drop;
@FXML
private StackPane preview;

private final ImageDropController controller = new ImageDropController();

public ImageDropView() {
try {
var loader = new FXMLLoader(getClass().getResource("ImageDropView.fxml"));
loader.setController(this);
this.root = loader.load();
} catch (IOException e) {
throw new RuntimeException(e);
}
drop.setAcceptedExtensions(Set.of(".png", ".jpg", ".jpeg", ".webp"));
drop.setOnFilesDropped(controller::handleDroppedFiles);
}

public Parent getRoot() {
return root;
}
}
Класс DropViewFactory создает и возвращает корневой элемент указанного MediaType.

Код: Выделить всё

import javafx.scene.Parent;

public final class DropViewFactory {
public static Parent create(MediaType type) {
return switch (type) {
case IMAGE -> new ImageDropView().getRoot();
case VIDEO -> new VideoDropView().getRoot();
};
}
}

Код: Выделить всё

public enum MediaType {IMAGE, VIDEO}
Это классы Main Controller и Main соответственно

Код: Выделить всё

import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class MainController {
@FXML
private BorderPane root;

public void openImageDialog() {
open(MediaType.IMAGE, "Import Image");
}

public void openVideoDialog() {
open(MediaType.VIDEO, "Import Video");
}

private void open(MediaType type, String title) {
var stage = new Stage();
stage.setTitle(title);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setScene(new Scene(DropViewFactory.create(type), 900, 600));
stage.show();
}
}

Код: Выделить всё

import javafx.application.Application;
import javafx.stage.Stage;
import test.MainController;

public class Main extends Application {
@Override
public void start(Stage primaryStage) {
MainController mainController = new MainController();
mainController.openImageDialog();
}
}
Что я хочу сделать
Когда файлы перетаскиваются на DragAndDropPane, система устанавливает значок файла(ов). Например, если перетащить четыре файла, система отобразит форму с уменьшенной непрозрачностью. Я хочу заменить значки одним значком, который отображает количество перетаскиваемых элементов в правом нижнем углу.
В этих двух похожих вопросах (post1, post2) оба хотят одного и того же, но оба имеют перетаскиваемый элемент, поступающий из приложения JavaFX. Кроме того, в документации setDragView это работает, только если источник элемента поступает из приложения.

Подробнее здесь: https://stackoverflow.com/questions/797 ... s-file-sys
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»