Windows 7 Look and Feel for JFileChooser [duplicate] - java

I just added a standard "Open file" dialog to a small desktop app I'm writing, based on the JFileChooser entry of the Swing Tutorial. It's generating a window that looks like this:
but I would prefer to have a window that looks like this:
In other words, I want my file chooser to have Windows Vista/Windows 7's style, not Windows XP's. Is this possible in Swing? If so, how is it done? (For the purposes of this question, assume that the code will be running exclusively on Windows 7 computers.)

It does not appear this is supported in Swing in Java 6.
Currently, the simplest way I can find to open this dialog is through SWT, not Swing. SWT's FileDialog (javadoc) brings up this dialog. The following is a modification of SWT's FileDialog snippet to use an open instead of save dialog. I know this isn't exactly what you're looking for, but you could isolate this to a utility class and add swt.jar to your classpath for this functionality.
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 ();
}
}

Even native Windows applications can get this type of dialog displayed on Windows 7. This is usually controlled by flags in OPENFILENAME structure and its size passed in a call to WinAPI function GetOpenFileName. Swing (Java) uses hooks to get events from the Open File dialog; these events are passed differently between Windows XP and Windows 7 version.
So the answer is you can't control the look of FileChooser from Swing. However, when Java gets support for this new look, you'll get the new style automatically.
Another option is to use SWT, as suggested in this answer. Alternatively you can use JNA to call Windows API or write a native method to do this.

Java 8 may finally bring a solution to this, but unfortunately (for Swing apps) it comes only as the JavaFX class FileChooser:
I've tested this code from here and it indeed pops a modern dialog (Windows 7 here):
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);
To integrate this into a Swing app, you'll have to run it in the javafx thread via Platform.runLater (as seen here).
Please note that this will need you to initialize the javafx thread (in the example, this is done at the scene initialization, in new JFXPanel()).
To sum up, a ready to run solution in a swing app would look like this :
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);
});

A bit of a hack, and slightly less empowered than the Swing version, but have you considered using a java.awt.FileDialog? It should not just look like the Windows file chooser, but actually be one.

I don't believe Swing would cover that though it may, if it doesn't you may need to look at something like SWT, which would make use of the actual native component, or do a custom UI element, like something out of the "Filthy Rich Clients" book.

good question +1 , looks like as they "forgot" to implements something for Win7 (defaultLookAndFeel) into Java6, but for WinXP works correclty, and I hope too, that there must exists some Method/Properties for that
anyway you can try that with this code,
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() {
}
}

Couldn't make this work for directories though!! The DirectoryDialog throws us back to the tree style directory chooser which is the same as the one listed in the question. The problem is that it does not allow me to choose/select/open hidden folders. Nor does it allow for navigation to folders like AppData, ProgramData etc..
The Windows 7 style filedialog (swt) does allow navigation to these folders, but then again, does not allow for folder selection :(
Update
To view hidden folders use JFileChooser and have setFileHidingEnabled(false). The only mandate with this is that users need to have 'show hidden files, folders and drives' selected in the
Folder Options -> View
of Windows Explorer
You won't get the flexibility of an address bar, but if you were looking around for a non-tree like file chooser in Java, which also lets you browse/view Hidden files/folder - then this should suffice

John McCarthy's answer seems to be the best. Here some suggestions.
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.Image;
Add image on top left corner. It's important that you use "getResourceAsStream", you'll notice after export as 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));
}
User's home directory:
String filterPath = System.getProperty("user.home");
Get absolut pathname instead of filter-dependent pathname, which is wrong on other drive.
String absolutePath = dialog.open();

Since Swing emulates various L&F's, I guess your best bet would be to upgrade your JRE to the very latest and hope that the JFileChooser UI has been updated.

JFileChooser has always been a bit odd looking with Swing, also a bit slow.
Try using SWT's filechooser or you could wrap the C calls in JNA.

Related

Opening a PDF in a javafx aplication

I'm developing a javafx application that opens a PDF when I pres a button. I'm using the xdg-open command in linux like this:
String[] command = {"xdg-open",path}
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
but when i pres the button nothing happens.
I tested it in a different project and it opened the PDF without problem.
Any idea how can i fix this?
Here's the method that I use. A simple call to the Desktop.getDesktop().open() method will open any given File using the system's default application.
This will also open the file in a background Thread so your application doesn't hang while waiting for the file to load.
public static void openFile(File file) throws Exception {
if (Desktop.isDesktopSupported()) {
new Thread(() -> {
try {
Desktop.getDesktop().open(file);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
This code show the document in the default browser :
File file = new File("C:/filePath/Test.pdf");
HostServices hostServices = getHostServices();
hostServices.showDocument(file.getAbsolutePath());
I hope this help!!
I have used ICEpdf's org.icepdf.core.pobjects.Document to render the pages of my PDF's; as described here. This gives a ava.awt.image.BufferedImageper page. I convert this to a JavaFX node:
Image fxImage = SwingFXUtils.toFXImage(bufferedImage, null);
ImageView imageView = new ImageView(fxImage);
From there you can write your own simple paging viewer in JavaFX. The rendering is fast and the result looks as hoped for.

Get the path of a file via file explorer

First of all I'm sorry if this question has been asked before or if there is documentation about the topic but i didn't found anything.
I want to make a windows app that open windows file explorer and you can browse for and then select a mp3 file, so you can play it (and replay it) in this program. I know how to open file explorer, this is my code :
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class Main
{
public static void main(String[] args) throws IOException {
Desktop desktop = Desktop.getDesktop();
File dirToOpen = null;
try {
dirToOpen = new File("c:\\");
desktop.open(dirToOpen);
} catch (IllegalArgumentException iae) {
System.out.println("File Not Found");
}
}
}
But i don't know how to select an mp3 file and then get the path of the file, so i can play it later.
I don't think you are approaching this right. You should use something like a FileDialog to choose a file:
FileDialog fd = new FileDialog(new JFrame());
fd.setVisible(true);
File[] f = fd.getFiles();
if(f.length > 0){
System.out.println(fd.getFiles()[0].getAbsolutePath());
}
Since you are only getting 1 MP3 file, you only need the first index of the File array returned from the getFiles() method. Since it is a modal dialog, the rest of your application will wait until after you choose a file. If you want to get multiple files at once, just loop through this aforementioned Files array.
See the documentation here: https://docs.oracle.com/javase/7/docs/api/java/awt/FileDialog.html

Setting FileChooserUI property in UIManager to the system's

I want to have my JFileChooser use the system's LookAndFeel, but have the rest of my components use Nimbus. Since each platform provides a different FileChooserUI, how would I set the FileChooserUI property in UIManager to the system's LookAndFeel?
A component is created with the current LAF. So you can try something like:
Set LAF to the system LAF
Create the JFileChooser
Reset the LAF to Nimbus
Not sure is this will cause any problems with the file chooser or not.
If you are using windows you can use Windows file chooser :
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class FileSelection {
public static String getPath(){
String path =null;
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);
path=dialog.open();
shell.close();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
return path;
}
}
getPath() will returns the direct path to the selected file, but note that you must download org.eclips.swt package and add the .jar file to your class path.
You can download it here : Download
If you are not interesting of using this filechooser then Check this example.

How to make a button that, when clicked, opens the %appdata% directory?

I have made a button, but I don't now how to make it open a specific directory like %appdata% when the button is clicked on.
Here is the code ->
//---- button4 ----
button4.setText("Texture Packs");
button4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
JFileChooser fileChooser=new JFileChooser("%appdata%");
int status = fileChooser.showOpenDialog(this);
fileChooser.setMultiSelectionEnabled(false);
if(status == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
// do something on the selected file.
}
}
And I want to make something like this ->
private void button4MouseClicked(MouseEvent e) throws IOException {
open folder %appdata%
// Open the folder in the file explorer not in Java.
// When I click on the button, the folder is viewed with the file explorer on the screen
}
import java.awt.Desktop;
import java.io.File;
public class OpenAppData {
public static void main(String[] args) throws Exception {
// Horribly platform specific.
String appData = System.getenv("APPDATA");
File appDataDir = new File(appData);
// Get a sub-directory named 'texture'
File textureDir = new File(appDataDir, "texture");
Desktop.getDesktop().open(textureDir);
}
}
Execute a command using Runtime.exec(..). However, not every OS has the same file explorer, so you need to handle the OS.
Windows: Explorer /select, file
Mac: open -R file
Linux: xdg-open file
I wrote a FileExplorer class for the purpose of revealing files in the native file explorer, but you'll need to edit it to detect operating system.
http://textu.be/6
NOTE: This is if you wish to reveal individual files. To reveal directories, Desktop#open(File) is far simpler, as posted by Andrew Thompson.
If you are using Windows Vista and higher, System.getenv("APPDATA"); will return you C:\Users\(username}\AppData\Roaming, so you should go one time up, and use this path for filechooser,
Just a simple modified Andrew's example,
String appData = System.getenv("APPDATA");
File appDataDir = new File(appData); // TODO: this path should be changed!
JFileChooser fileChooser = new JFileChooser(appData);
fileChooser.showOpenDialog(new JFrame());
More about windows xp, and windows vista/7/8

showDocument() does not display new window in IE8 with Java 7/Java 6u27

I have a Java Applet that interacts with the Java Plugin to show a document (just a URL) in a named browser window:
public class TestApplet extends Applet {
#Override
public void init() {
super.init();
final JButton showButton = new JButton("Show Google!");
showButton.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
try {
getAppletContext().showDocument(new URL("http://google.com"), "Some Window Title");
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
}
});
add(showButton);
}
}
This has worked historically but starting with Java 7 and Java 6u27, the window fails to open in Internet Explorer (tested in IE 8). If I use _blank as the window title (target) instead of Google, the window opens correctly (albeit in a new window each time).
I've tracked down this bug that was fixed for 6u27:
Vista/IE7 further showDocument focus issue with named targeted windows
Has anybody else experienced the same behaviour? Have you found a workaround (other than using "_blank")?
Edit
Updated the example. I wasn't actually using "Google" as the target, I was using "Some Window Title" (sorry!). It seems like this problem is unique to targets with spaces in the name.
It seems like this problem is unique to targets with spaces in the name.
Two possible solutions:
Replace the " " with "%20"
Don't use a space in the name of the target! (Though I thought that would be a 'no brainer'.)
Try this code, it should work.
Desktop desktop = Desktop.getDesktop();
desktop.browse(new URI(info));

Categories