Bringing Jfilechooser on Top of All Windows

Bringing JFileChooser on top of all windows

The API for showOpenDialog() refers to showDialog(), which says, "If the parent is null, then the dialog depends on no visible window, and it's placed in a look-and-feel-dependent position such as the center of the screen."

The example below positions the chooser in the center of the screen on my L&F. You might see how it compares to yours.

package gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;

/**
* @see http://stackoverflow.com/questions/8507521
* @see http://stackoverflow.com/questions/5129294
*/
public class ImageApp extends JPanel {

private static final int MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private JFileChooser chooser = new JFileChooser();
private Action openAction = new ImageOpenAction("Open");
private Action clearAction = new ClearAction("Clear");
private JPopupMenu popup = new JPopupMenu();
private BufferedImage image;

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new ImageApp().create();
}
});
}

public void create() {
JFrame f = new JFrame();
f.setTitle("Title");
f.add(new JScrollPane(this), BorderLayout.CENTER);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
menu.setMnemonic('F');
menu.add(new JMenuItem(openAction));
menu.add(new JMenuItem(clearAction));
menuBar.add(menu);
f.setJMenuBar(menuBar);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setSize(new Dimension(640, 480));
f.setLocationRelativeTo(null);
f.setVisible(true);
}

public ImageApp() {
this.setComponentPopupMenu(popup);
popup.add("Popup Menu");
popup.add(new JMenuItem(openAction));
popup.add(new JMenuItem(clearAction));
}

@Override
public Dimension getPreferredSize() {
if (image == null) {
return new Dimension();
} else {
return new Dimension(image.getWidth(), image.getHeight());
}
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}

private class ClearAction extends AbstractAction {

public ClearAction(String name) {
super(name);
this.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_C);
this.putValue(Action.ACCELERATOR_KEY,
KeyStroke.getKeyStroke(KeyEvent.VK_C, MASK));
}

@Override
public void actionPerformed(ActionEvent e) {
image = null;
revalidate();
repaint();
}
}

private class ImageOpenAction extends AbstractAction {

public ImageOpenAction(String name) {
super(name);
this.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_O);
this.putValue(Action.ACCELERATOR_KEY,
KeyStroke.getKeyStroke(KeyEvent.VK_O, MASK));
}

@Override
public void actionPerformed(ActionEvent e) {
int returnVal = chooser.showOpenDialog(chooser);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
try {
image = ImageIO.read(f);
revalidate();
repaint();
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}
}
}
}

JFileChooser in front of fullscreen Swing application

Unfortunately I can't say how you realised the implementation of the fullscreen app. But I tried a few things and came up with this:

import java.awt.Color;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Gui extends JFrame {

public Gui() {

this.setDefaultCloseOperation(EXIT_ON_CLOSE);

//this.setSize(java.awt.Toolkit.getDefaultToolkit().getScreenSize());
// Set some charateristics of the frame
this.setExtendedState(Frame.MAXIMIZED_BOTH);
this.setBackground(Color.black);
this.setUndecorated(true);

JButton a = new JButton("PRESS ME!");

a.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser fc = new JFileChooser();
fc.showOpenDialog(getParent());
}
});

this.add(a);

this.setVisible(true);

}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new Gui();
}
});
}
}

Pay attention to the fact, that I created a new JFileChooser with the parent of the current JFrame as parameter.

EDIT:
I now even tried to set

java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(new Gui());

and without the

this.setUndecorated(true);

it worked for me (got a nice fullscreen view and the JFileChooser was in the front). I believe the problem with the window decoration is linked to my window manager (I'm using linux with gnome).

Hopefully this solution works for you, if not:
Could you explain a little bit more, how you create the fullscreen app?

JFileChooser from a command line program and popping up Underneath all windows

So after trying a variety of things from different stack overflow topics I ended up with a result that consistently and reliably opens above every window on Windows 7.

public class ChooseFile {
private JFrame frame;
public ChooseFile() {
frame = new JFrame();

frame.setVisible(true);
BringToFront();
}
public File getFile() {
JFileChooser fc = new JFileChooser();
if(JFileChooser.APPROVE_OPTION == fc.showOpenDialog(null)){
frame.setVisible(false);
return fc.getSelectedFile();
}else {
System.out.println("Next time select a file.");
System.exit(1);
}
return null;
}

private void BringToFront() {
frame.setExtendedState(JFrame.ICONIFIED);
frame.setExtendedState(JFrame.NORMAL);

}

}

As it stands in my program it is an inner class and is invoked by calling:

System.out.println("Please select the file");
g.inputFile = g.new ChooseFile().getFile();

How to open FileDialog on top of all windows

I don't understand why using a JFileChooser should hang your application when used on a MAC...it shouldn't but then again I've read that Swing can do strange things on a MACs due to the EDT. I can't personally confirm that however since I've never worked on a MAC.

One solution might be to run the dialog in a separate thread thus allowing the JFileChooser to function independently from the EDT and therefore not posing any threat to it.

As for your File Chooser dialog hiding behind your Swing application, I think it may be because of the fact that your application's JFrame is set to be Always-On-Top and even though the FileChooser dialog is considered modal (which it is) doesn't mean that it will be displayed above everything if null is used as its Parent component. The parent itself for the dialog should also be set to be Always-On-Top as well. This is usually the case regardless of what Operating System a dialog is displayed in. The following code should work regardless of what the JFileChooser or JOptionPane (, etc) dialog might be for a parent or if there is in fact no parent at all:

final JFrame iFRAME = new JFrame();
iFRAME.setAlwaysOnTop(true); // ****
iFRAME.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
iFRAME.setLocationRelativeTo(null);
iFRAME.requestFocus();

JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = jfc.showOpenDialog(iFRAME);
iFRAME.dispose();
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
// Display selected file in console
System.out.println(selectedFile.getAbsolutePath());
}
else {
System.out.println("No File Selected!");
}

And for the fact that your application crashes when run in a MAC you might want to try this:

final JFrame iFRAME = new JFrame();
iFRAME.setAlwaysOnTop(true); // ****
iFRAME.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
iFRAME.setLocationRelativeTo(null);
iFRAME.requestFocus();

EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFileChooser jfc = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
int returnValue = jfc.showOpenDialog(iFRAME); // ****
iFRAME.dispose();
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
// Display selected file in console
System.out.println(selectedFile.getAbsolutePath());
}
else {
System.out.println("No File Selected!");
}
}
});

How to bring a window to the front?

A possible solution is:

java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
myFrame.toFront();
myFrame.repaint();
}
});

How to open a file after clicking the open button in jFileChooser?

I usually don't embed the chooser in the top-level Frame or add an action listener, instead I add a button or menu option to the frame to trigger when to show the chooser, then wait for showOpenDialog() to return and then call getSelectedFile().

What I usually do is this:

public class MyJFrame extends javax.swing.JFrame {

public MyJFrame() {
JButton btn = new JButton("open file");
add(btn);
btn.addActionListener(e -> {
selectFile();
});
pack();
setVisible(true);
}

public void selectFile() {
JFileChooser chooser = new JFileChooser();
// optionally set chooser options ...
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
File f = chooser.getSelectedFile();
// read and/or display the file somehow. ....
} else {
// user changed their mind
}
}
}


Related Topics



Leave a reply



Submit