JFilechooser change default appearance - java

A JFileChooser used to select a directory is initialized using:
JFileChooser directoryChooser = new JFileChooser();
directoryChooser.setDialogTitle("Choose Directory");
directoryChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
directoryChooser.setAcceptAllFileFilterUsed(false);
and opened using:
directoryChooser.updateUI();
directoryChooser.showOpenDialog(null);
File selectedFile = directoryChooser.getSelectedFile();
which works and i can select a directory but i don't like it's appearance:
I would like it to have the same appearance as the DirectoryChooser in JavaFx, which is also the same appearance for example as the open/save dialog in Chrome & Firefox. That would also make it possible to enter the path manually.
Is it possible to achieve what i want without using JavaFx and if so how can i change it's appearance?

Update
I noticed that you edited your question to include the text "without using JavaFx". As this answer is using JavaFX, and you don't wish to use that technology, you can ignore it.
As you state "I would like it to have the same appearance as the DirectoryChooser in JavaFx", then you may as well just use the DirectoryChooser from JavaFX from within your Swing application.
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.stage.DirectoryChooser;
import javax.swing.*;
import java.io.File;
public class SwingWithJavaFXDirectoryChooser {
private static void createAndShowGUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// creating a new JFXPanel (even if we don't use it), will initialize the JavaFX toolkit.
new JFXPanel();
DirectoryChooser directoryChooser = new DirectoryChooser();
JButton button = new JButton("Choose directory");
button.addActionListener(e ->
// runLater is called to create the directory chooser on the JavaFX application thread.
Platform.runLater(() -> {
File selectedDirectory = directoryChooser.showDialog(null);
System.out.println(selectedDirectory);
})
);
frame.getContentPane().add(button);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(SwingWithJavaFXDirectoryChooser::createAndShowGUI);
}
}

Related

Wait for user input Java Swing

I am using JAVA Swing to create a very basic UI. When I run the program, a window will open with a message and browse button(using frame and JButtons for the same). On click of browse button, another window will open to navigate to the file. This I have achieved by calling a FileChooser on the click event of Browse button. However, my program does not wait for user input. The first window with browse button opens and program keeps on executing and ends up in an error as no file has been selected. How do I halt the execution till user input is provided?
In a forum it was advised to use showOpenDialog() method of browser but that straightway opens a browsing window, whereas I want to give the provision to user to click on Browse buttonbrowsewindow
pick file window
My code is below
frame.setLayout(new FlowLayout());
// set up a file picker component
JFilePicker filePicker = new JFilePicker("Pick a file", "Browse...");
filePicker.setMode(JFilePicker.MODE_OPEN);
filePicker.addFileTypeFilter(".jpg", "JPEG Images");
filePicker.addFileTypeFilter(".mp4", "MPEG-4 Videos");
// access JFileChooser class directly
JFileChooser fileChooser = filePicker.getFileChooser();
fileChooser.setCurrentDirectory(new File("C:/"));
// add the component to the frame
frame.add(filePicker);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(520, 100);
frame.setLocationRelativeTo(null); // center on screen
frame.setVisible(true);
System.out.println();
JPicker is the custom class which creates a filechooser and sets things to be done on click of Browse button
Of Course, You set the JFrame visible at the end of its' initialization. You need to do this within the main() method of your startup class. Where is yours?
The JFilePicker (created by: Nam Ha Minh) is applied to a JFrame as a Java Component in order to save a little time in GUI development. I personally would just use the JFileChooser directly within a JButton ActionPerformed event. If you had followed the directions properly then you would see that you need a main() method which only makes sense. What your application Startup class should look like is something like this:
import java.awt.FlowLayout;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TestJFilePicker extends JFrame {
private static final long serialVersionUID = 1L;
public TestJFilePicker() {
super("Test using JFilePicker");
setLayout(new FlowLayout());
// set up a file picker component
JFilePicker filePicker = new JFilePicker("Pick a file", "Browse...");
filePicker.setMode(JFilePicker.MODE_OPEN);
filePicker.addFileTypeFilter(".jpg", "JPEG Images");
filePicker.addFileTypeFilter(".mp4", "MPEG-4 Videos");
// access JFileChooser class directly
JFileChooser fileChooser = filePicker.getFileChooser();
fileChooser.setCurrentDirectory(new File("D:/"));
// add the component to the frame
add(filePicker);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(520, 100);
setLocationRelativeTo(null); // center on screen
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestJFilePicker().setVisible(true);
}
});
}
}
The above code (which is the work of Nam Ha Minh) of course assumes that you have already applied the JFilePicker and the FileTypeFilter class files to your project. Without them the above code will not work.

How to add an ImageIcon to a JToolBar

I am trying to add a icon to a toolbar but what is the best place to put it in? My desktop or should I make a new file in the project file or add all the pictures in because it is not showing and this is my code:
JToolBar toolBar = new JToolBar();
String[] iconFiles = {"pen-icon","",""};
String[] buttonLabels = {"New","Open","Save"};
icon = new ImageIcon[iconFiles.length];
Obutton = new JButton[buttonLabels.length];
for (int i = 0; i < buttonLabels.length; ++i) {
icon[i] = new ImageIcon(iconFiles[i]);
Obutton[i] = new JButton(icon[i]);
Obutton[i].setToolTipText(buttonLabels[i]);
if (i == 3)
toolBar.addSeparator();
toolBar.add(Obutton[i]);
}
I would use an Action. Here is the AbstractAction constructor
public AbstractAction(String name, Icon icon) - Creates an Action with the specified name and small icon.
Parameters:
name - the name (Action.NAME) for the action; a value of null is ignored
icon - the small icon (Action.SMALL_ICON) for the action; a value of null is ignored
The benefit of using an Action is that is can be reused for components with similar purposes. So say you want to have an icon button in the toolbar to open a file, and also have a JMenuItem in a JMenu that also opens a file. They could share the same action, thus sharing the same icon, action command, and action to perform.
Action action = new AbstractAction("someActionCommand", someIcon) {
#Override
public void actionPerformed(ActionEvent e) {
// do something.
}
};
toolbar.add(action);
The above will automatically put the icon for you, but not the String. In a JMenuItem it would put both the String and the icon.
Then just add the Action to the tool bar.
See more at How to use Actions
To answer you real question, as #MadProgrammer noted, you should be loading your images as an embedded resource, using
ImageIcon icon = new ImageIcon(MyClass.class.getResource("/resources/images/image.png"));
where the /resources/images directory is in the src, and getResource() returns a URL. Upon build, your IDE should copy the files into the class path for you.
ProjectRoot
src
resources
images
image.png
You'll come to find that when using a file from the file system, will not work upon time of deployment
Here's an example, where the JMenuItem and the JToolBar button share the same action. Notice that in the JToolBar all I have to do is add the Action, I don't need to create a button for it. The JToolBar automatically makes it a button, without the action command
I use this "open.gif" from the below file structure and use
ImageIcon icon = new ImageIcon(
ActionTest.class.getResource("/resources/image/open.gif"));
Here's the result
Here's the code. Enjoy!
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class ActionTest {
public ActionTest() {
ImageIcon openIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/open.gif"));
ImageIcon saveIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/save.gif"));
ImageIcon newIcon = new ImageIcon(
ActionTest.class.getResource("/resources/image/new.gif"));
Action openAction = new AbstractAction("Open", openIcon) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open File");
}
};
Action saveAction = new AbstractAction("Save", saveIcon) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Save File");
}
};
Action newAction = new AbstractAction("New", newIcon) {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("New File");
}
};
JMenuItem openMenuItem = new JMenuItem(openAction);
JMenuItem saveMenuItem = new JMenuItem(saveAction);
JMenuItem newMenuItem = new JMenuItem(newAction);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.add(openMenuItem);
fileMenu.add(saveMenuItem);
fileMenu.add(newMenuItem);
menuBar.add(fileMenu);
JToolBar toolBar = new JToolBar();
toolBar.add(Box.createHorizontalGlue());
toolBar.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));
toolBar.add(newAction);
toolBar.add(openAction);
toolBar.add(saveAction);
JFrame frame = new JFrame("Toolbar and Menu Test");
frame.setJMenuBar(menuBar);
frame.add(toolBar, BorderLayout.PAGE_START);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ActionTest();
}
});
}
}
Resources of this type are typically best contained within the application context (such as a jar file). This reduces the chances of someone tampering with it as it's much more time consuming to unpack, modify and repack a jar file then simply replace a file. It also reduces what you need to distribute as it becomes self-contained.
These are known as embedded resources.
Where you would put them within this context is up to up, many people use a "resources" folder to store these types of files, but sometimes, you may want something that is relative to the context of the class. It's up to you.
This raises issues with loading these resources, as you can no longer reference them using something like File.
In general you can use Class#getResource(String), which returns a URL or Class#getResourceAsStream(String) which returns a InputStream. This provides you with all you need to load these embedded resources.
ImageIcon(String) expects the value to be a file reference, which means it won't work for embedded resources, but ImageIcon provides a constructor that takes a URL as a reference, this means you would need to use
icon[i] = new ImageIcon(getClass().getResource(iconFiles[i]));
To load your images.
Based on your example, the images would need to be relative to the class (ie within a directory structure the same as your package structure). How you achieve this will depend on your development environment.
Remember, you can also specify relative paths to getResource and even an absolute path in some contexts. An absolute path basic prefixes the elements of class path to the specified path when it searches for the resources.

FileChooser.showOpenDialog showing default java icon on top of the frame

I have created a FileChooser in my swing application. when I click on open ,the open dialog box showing default image(java) on top of the frame instead of custom image which i was set for my JFrame.
Sample Code:
JFileChooser filec=new JFileChooser();
int fileval=filec.showOpenDialog(myjframe);
I found some times it is working fine.please help me on this.
You can set the image in the parent JFrame of the JFileChooser which will be reflected in the dialog:
Image image = ImageIO.read(getClass().getResource("MyImage.png"));
myjframe.setIconImage(image);
It seems to work reliably here with this SSCCE. Does this code work reliably where you are?
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class FileChooserIcon {
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
Image image =
new BufferedImage(32,32,BufferedImage.TYPE_INT_RGB);
JFrame f = new JFrame("Demo");
f.setIconImage(image);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
// See http://stackoverflow.com/a/7143398/418556 for demo.
f.setLocationByPlatform(true);
f.pack();
f.setSize(600,400);
f.setVisible(true);
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(f);
}
};
SwingUtilities.invokeLater(r);
}
}
JFrame f = new JFrame("Edit Configure File");
//Use first two ways getting error: non-static method getClass() cannot be referenced from a static context
//(1) Image image = ImageIO.read(getClass().getResource("images/ctx.Icon"));
//f.setIconImage(image);
//(2) f.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("images/ctx.PNG")));
//(3) Use third way. It works for me
f.setIconImage(new ImageIcon("images/ctx.PNG").getImage());

refresh the contents of frame in real time [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
When does one need to call revalidate() on a swing component to make it refresh, and when not?
i am making a Explorer program in Java it works as follows
i input the path from the user, a textbox after the user presses enter the path is set and the list is computed of the folder and corresponding labels are created which are supposed to be displayed on the window but the application doesn't display the new contents of the folder, if i change the text then it directs to a new directory so when i press enter then it must show the contents of the new directory loaded but only after resizing the window does it show the new contents of the frame
the code is as follows
package explorer;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Explorer extends JFrame{
File file;
Scanner scan;
String path;
String [] listOfFiles;
JTextField txtPath;
JLabel lblLocation;
JLabel child[];
JPanel childPanel;
JPanel masterPanel;
public Explorer(){
lblLocation = new JLabel("Location: ");
/*
* the declaration of panels
*/
masterPanel = new JPanel();
childPanel = new JPanel();
JPanel panel = new JPanel();
/*declaration of other components*/
txtPath = new JTextField("",20);
/*addition of components to panel for layout*/
panel.add(lblLocation);
panel.add(txtPath);
/*adding to master panel, for sophisticated layout*/
masterPanel.add(panel, BorderLayout.NORTH);
masterPanel.add(childPanel, BorderLayout.SOUTH);
getContentPane().add(masterPanel);
/*this place from where address is fetched like /home/revolution/Desktop etc on ubuntu*/
txtPath.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ev){
childPanel.removeAll();
path = new String(txtPath.getText());//the absolute path
file = new File(path);
File childFiles[];
String name = path.substring(path.lastIndexOf('/')+1, path.length());//the name of the directory being displayed
setTitle(name);
if(!file.isDirectory()){
JOptionPane.showMessageDialog(null, "Error file is not a directory");
} else {
listOfFiles = file.list();
child = new JLabel[listOfFiles.length];// labels equal to the number fo files and with name of the coresponding file/folder
childFiles = new File[listOfFiles.length];//references to files
childPanel.setLayout(new GridLayout(listOfFiles.length/2,listOfFiles.length/2));//setting grid layout
for(int i=0; i<listOfFiles.length;i++){
childFiles[i] = new File(listOfFiles[i]);
child[i] = new JLabel(listOfFiles[i]);
child[i].setToolTipText(childFiles[i].isFile()?"File":"Folder");
childPanel.add(child[i]);
}
childPanel.setVisible(true);
}
}
});
}
}
what is wrong? how can i 'refresh' the contents of the window??
I think you need to revalidate() the panel.
More precisely at the end of your action listener you can add childPanel.revalidate();
childPanel.setVisible(true);
}
}
childPanel.revalidate();
});

How to put an image icon, which is taken with JFileChooser, on a label?

Hey there, i have just tried to put an image that is taken with JFileChooser on a label; but it did not work the way i want to. Here is the code that i tried;
import java.io.*;
import javax.swing.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
JFileChooser chooser = new JFileChooser();
JFrame frame = new JFrame("My Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
chooser.showOpenDialog(null);
File file = chooser.getSelectedFile();
ImageIcon icon = new ImageIcon(file.getName());
JLabel label = new JLabel(icon);
// JLabel label2 = new JLabel("try try catch it");
panel.add(label);
// panel.add(label2);
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
Any suggestion?
Close.
You will notice that when you look at file.getName() you see that it will give you the name of the file that you selected. You're looking for the path instead of the name of the file.
See if you can look in the API for File for how to get the path.
You should be using file.getPath() instead of file.getName(). You should also be doing your painting work in the EDT.

Categories