Только решение с java.awt.Desktop
работал для меня, чтобы открыть файл с JavaFX.
Однако сначала мое приложение застряло, и мне пришлось выяснить, что необходимо позвонить Desktop#open(File file)
из новой темы. Вызов метода из текущего потока или потока приложений JavaFX Platform#runLater(Runnable runnable)
привел к тому, что приложение зависало бесконечно без исключения исключения.
Это небольшой пример JavaFX приложения с рабочего открытия файла решения:
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class FileOpenDemo extends Application {
@Override
public void start(Stage primaryStage) {
final Button button = new Button("Open file");
button.setOnAction(event -> {
final FileChooser fileChooser = new FileChooser();
final File file = fileChooser.showOpenDialog(primaryStage.getOwner());
if (file == null)
return;
System.out.println("File selected: " + file.getName());
if (!Desktop.isDesktopSupported()) {
System.out.println("Desktop not supported");
return;
}
if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) {
System.out.println("File opening not supported");
return;
}
final Task<Void> task = new Task<Void>() {
@Override
public Void call() throws Exception {
try {
Desktop.getDesktop().open(file);
} catch (IOException e) {
System.err.println(e.toString());
}
return null;
}
};
final Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();
});
primaryStage.setScene(new Scene(button));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Другой Предлагаемое решение с javafx.application.HostServices
не работает. Я использую OpenJFX 8u141 на Ubuntu 17.10 amd64, и я получил следующее исключение при вызове HostServices#showDocument(String uri)
:
java.lang.ClassNotFoundException: com.sun.deploy.uitoolkit.impl.fx.HostServicesFactory
Очевидно, что JavaFX HostServices еще не реализована должным образом на всех платформах. По этой теме смотрите также: https://github.com/Qabel/qabel-desktop/issues/420
Всякий раз, когда я пробовал это с URL-адресом (включая файл: // URL), который сопоставляется с определенным документом, он открывает документ по умолчанию для этого типа документа. Не работает ли это так же для СМИ и т. Д.? Вероятно, лучше избегать смешивания AWT и JavaFX (что принято в этом случае), если вы можете это сделать разумно. –
Да, если он содержит 'файл: //' Я столкнулся с 'IllegalArgumentException'. Я не заметил, прежде чем читать ваши комментарии, что это от AWT. Я был бы очень признателен, если бы вы поделились своим ответом, как я могу это сделать с помощью JavaFX, который также обогатит мои знания и опыт. –
Ну, я просто проверил снова, и он работает с файлами: // URL, но не будет работать с другими типами документов с http: URL (он открывает браузер, который загружает файл). Я добавлю ответ, но если вы хотите открыть носитель, который загружается с веб-сервера, я не уверен, что есть способ сделать это. –