Поддерживает ли Swing поддержку файлов в стиле Windows 7? - программирование
Подтвердить что ты не робот

Поддерживает ли Swing поддержку файлов в стиле Windows 7?

Я просто добавил стандартный " Открыть файл" на маленьком настольном приложении, которое я пишу, на основе JFileChooser Ввод учебника Swing. Он генерирует окно, которое выглядит так:

screenshot of unwanted/XP-style window

но я бы предпочел иметь окно, которое выглядит так:

screenshot of desired/7-style window

Другими словами, я хочу, чтобы мой выбор файла имел стиль Windows Vista/Windows 7, а не Windows XP. Возможно ли это в Swing? Если да, то как это делается? (Для целей этого вопроса предположим, что код будет работать исключительно на компьютерах под управлением Windows 7.)

4b9b3361

Ответ 1

Не похоже, что это поддерживается в Swing в Java 6.

В настоящее время самый простой способ открыть этот диалог - через SWT, а не Swing. SWT FileDialog (javadoc) вызывает этот диалог. Ниже приведена модификация SWT фрагмента FileDialog для использования диалогового окна open, а не сохранения. Я знаю, что это не совсем то, что вы ищете, но вы можете выделить это в класс утилиты и добавить swt.jar в свой класс для этой функции.

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;

public class SWTFileOpenSnippet {
    public static void main (String [] args) {
        Display display = new Display ();
        Shell shell = new Shell (display);
        // Don't show the shell.
        //shell.open ();  
        FileDialog dialog = new FileDialog (shell, SWT.OPEN | SWT.MULTI);
        String [] filterNames = new String [] {"All Files (*)"};
        String [] filterExtensions = new String [] {"*"};
        String filterPath = "c:\\";
        dialog.setFilterNames (filterNames);
        dialog.setFilterExtensions (filterExtensions);
        dialog.setFilterPath (filterPath);
        dialog.open();
        System.out.println ("Selected files: ");
        String[] selectedFileNames = dialog.getFileNames();
        for(String fileName : selectedFileNames) {
            System.out.println("  " + fileName);
        }
        shell.close();
        while (!shell.isDisposed ()) {
            if (!display.readAndDispatch ()) display.sleep ();
        }
        display.dispose ();
    }
} 

Ответ 2

Даже собственные приложения Windows могут получить этот тип диалогового окна, отображаемого в Windows 7. Обычно это контролируется флагами в OPENFILENAME и его размер передавался при вызове функции WinAPI GetOpenFileName. Swing (Java) использует крючки для получения событий из диалогового окна "Открыть файл"; эти события передаются по-разному между версией Windows XP и Windows 7.

Итак, ответ: вы не можете контролировать внешний вид FileChooser от Swing. Однако, когда Java получает поддержку этого нового вида, вы автоматически получите новый стиль.

Другой вариант - использовать SWT, как предложено в этом ответе. В качестве альтернативы вы можете использовать JNA для вызова Windows API или для написания собственного метода.

Ответ 3

Немного взлома и немного меньше, чем версия Swing, но вы считаете, что используете java.awt.FileDialog? Он не должен выглядеть просто как файл выбора Windows, но на самом деле он один.

Ответ 4

Я не считаю, что Swing будет охватывать это, хотя может, если это не так, вам может понадобиться посмотреть что-то вроде SWT, которое будет использовать фактический собственный компонент или сделать пользовательский элемент пользовательского интерфейса, например, что-то из книги "Грязные богатые клиенты".

Ответ 5

Java 8 может, наконец, принести решение, но, к сожалению (для Swing-приложений), он приходит только как класс JavaFX FileChooser:

Я проверил этот код здесь, и он действительно выдает современный диалог (здесь Windows 7):

FileChooser fileChooser = new FileChooser();

//Set extension filter
FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG");
FileChooser.ExtensionFilter extFilterPNG = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.PNG");
fileChooser.getExtensionFilters().addAll(extFilterJPG, extFilterPNG);

//Show open file dialog
File file = fileChooser.showOpenDialog(null);

Чтобы интегрировать это в приложение Swing, вам нужно запустить его в потоке javafx через Platform.runLater (как показано здесь).

Обратите внимание, что вам понадобится инициализировать поток javafx (в примере это выполняется при инициализации сцены в new JFXPanel()).

Подводя итог, готовое к запуску решение в приложении swing будет выглядеть так:

new JFXPanel(); // used for initializing javafx thread (ideally called once)
Platform.runLater(() -> {
    FileChooser fileChooser = new FileChooser();

    //Set extension filter
    FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG");
    FileChooser.ExtensionFilter extFilterPNG = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.PNG");
    fileChooser.getExtensionFilters().addAll(extFilterJPG, extFilterPNG);

    //Show open file dialog
    File file = fileChooser.showOpenDialog(null);
});

Ответ 6

Хороший вопрос +1, выглядит так, как они "забыли" для реализации чего-то для Win7 (defaultLookAndFeel) в Java6, но для WinXP работает корреляция, и я тоже надеюсь, что там должен существовать некоторый Method/Properties для

В любом случае вы можете попробовать это с помощью этого кода,

import java.io.File;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;

class ChooserFilterTest {

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                String[] properties = {"os.name", "java.version", "java.vm.version", "java.vendor"};
                for (String property : properties) {
                    System.out.println(property + ": " + System.getProperty(property));
                }
                JFileChooser jfc = new JFileChooser();
                jfc.showOpenDialog(null);
                jfc.addChoosableFileFilter(new FileFilter() {

                    @Override
                    public boolean accept(File f) {
                        return f.isDirectory() || f.getName().toLowerCase().endsWith(".obj");
                    }

                    @Override
                    public String getDescription() {
                        return "Wavefront OBJ (*.obj)";
                    }

                    @Override
                    public String toString() {
                        return getDescription();
                    }
                });
                int result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?");
                System.out.println("Displayed description (Metal): " + (result == JOptionPane.YES_OPTION));
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    SwingUtilities.updateComponentTreeUI(jfc);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                jfc.showOpenDialog(null);
                result = JOptionPane.showConfirmDialog(null, "Description was 'All Files'?");
                System.out.println("Displayed description (System): " + (result == JOptionPane.YES_OPTION));
            }
        };
        SwingUtilities.invokeLater(r);
    }

    private ChooserFilterTest() {
    }
}

Ответ 7

Не удалось сделать эту работу для каталогов! DirectoryDialog отбрасывает нас обратно в список выбора стиля дерева, который совпадает с тем, который указан в вопросе. Проблема в том, что он не позволяет мне выбирать/выбирать/открывать скрытые папки. Также он не позволяет осуществлять навигацию по таким папкам, как AppData, ProgramData и т.д.

Элемент filedialog (swt) в стиле Windows 7 разрешает навигацию к этим папкам, но опять же не позволяет выбирать папку: (

Обновление Для просмотра скрытых папок используйте JFileChooser и setFileHidingEnabled(false). Единственный мандат в этом заключается в том, что пользователям нужно "показывать скрытые файлы, папки и диски", выбранные в

Свойства папки → Просмотр

проводника Windows

Вы не получите гибкости адресной строки, но если бы вы искали альтернативный вариант выбора файлов в Java, который также позволяет просматривать/просматривать скрытые файлы/папку - тогда этого должно быть достаточно

Ответ 8

Ответ Джона Маккарти кажется лучшим. Вот несколько советов.

import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.Image;

Добавить изображение в верхнем левом углу. Важно, чтобы вы использовали "getResourceAsStream", вы заметите, что после экспорта в качестве Runnable jar:

Display display = new Display();
Shell shell = new Shell(display);
InputStream inputImage = getClass().getResourceAsStream("/app/launcher.png");
if (inputImage != null) {
    shell.setImage(new Image(display, inputImage));
}

Домашний каталог пользователя:

String filterPath = System.getProperty("user.home");

Получить абсолютное имя пути вместо зависимого от фильтра пути, что неверно на другом диске.

String absolutePath = dialog.open();

Ответ 9

Поскольку Swing эмулирует различные L & F, я полагаю, что лучше всего будет обновить JRE до самого последнего и надеяться, что пользовательский интерфейс JFileChooser будет обновлен.

Ответ 10

JFileChooser всегда был немного странным, глядя с Swing, также немного медленным.

Попробуйте использовать SWT filechooser, или вы можете обернуть вызовы C в JNA.