Поддерживает ли 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.)
Ответы
Ответ 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.