I really need your help, cause I'm struggling with it. I've created a JFrame in which I can open up a JDialog for e.g. changing settings. In the JDialog there is a button for starting a JFileChooser. I'm able to choose a file and everything works fine. But if I'm just closing the JFileChooser AND the JDialog, the JFrame will disable and minimize.
Does anyone know how to fix that?
Building JFrame:
frame = new JFrame("My first JFrame");
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
closeWindow();
}
});
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Cancel");
frame.getRootPane().getActionMap().put("Cancel", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
closeWindow();
}
});
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
[...]
frame.getContentPane().setLayout(null);
frame.setVisible(true);
Building JDialog:
final EditColumnsDialog editColumnsDialog = new EditColumnsDialog(frame, ...);
editColumnsDialog.editPicPath();
...
class EditColumnsDialog extends JDialog {
EditColumnsDialog(final JFrame owner, ...) throws Exception {
super(owner, owner.getTitle());
[...]
}
...
protected void editPicPath() {
[...]
JButton searchButton = new JButton("Search");
searchButton.setVisible(true);
searchButton.addActionListener(e -> {
File folder = WindowBuilder.fileChooser(JFileChooser.DIRECTORIES_ONLY, picPath.getText());
if (folder != null) {
picPath.setText(folder.getAbsolutePath());
}
});
[...]
pack();
setVisible(true);
setModal(true);
}
}
Building JFileChooser:
static File fileChooser(final int fileSelectionMode, final String dir) {
JFileChooser jFileChooser = new JFileChooser();
jFileChooser.setFileSelectionMode(fileSelectionMode);
jFileChooser.setCurrentDirectory(new File(dir));
Action details = jFileChooser.getActionMap().get("viewTypeDetails");
details.actionPerformed(null);
if (jFileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
return jFileChooser.getSelectedFile();
} else {
return null;
}
}
Found the solution:
in EditColumnsDialog (JDialog) setting "setModal(true)" BEFORE (!!!) "setVisible(true)"
This will ensure that the new window (JDialog) opened in a JFrame is blocking the old window, then the JFileChooser window is blocking the JDialog and after closing it the other one will gain focus.
Related
I'm running an application with similar behaviour to that in the test case below.
The problem is that when you switch focus to a different window by clicking on it and keeping the below application frame in view and then click directly into the text field with the focusGained listener, close the dialog and then all key input will be lost to the all of the text fields in the application.
If you click anywhere in the application first or the icon in the task bar to gain focus back then this does not occur.
This is Java 8 specific - in Java 7 it will not lose focus, not sure about java 9 but that is not an option anyway
The test case below demonstrates this behaviour.
public class FocusTest extends JFrame
{
JTextField noFocus;
public static void main(String[] args)
{
FocusTest ft = new FocusTest();
ft.setVisible(true);
}
public FocusTest()
{
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100,100,300,150);
setLayout(new GridLayout(3,1, 2, 2));
setTitle("Losing keyboard...");
noFocus = new JTextField();
add(noFocus);
JTextField jft = new JTextField();
jft.addFocusListener(new FocusAdapter()
{
#Override
public void focusGained(FocusEvent e)
{
createDialog().setVisible(true);
noFocus.requestFocusInWindow();
}
});
add(jft);
JButton jb = new JButton("OPEN");
jb.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("OPEN"))
createDialog().setVisible(true);
}
});
add(jb);
}
private JDialog createDialog()
{
final JDialog jd = new JDialog(this, true);
jd.setLocationRelativeTo(this);
jd.setLayout(new BorderLayout());
jd.getContentPane().add(new JTextField(), BorderLayout.CENTER);
JButton jb = new JButton("Close");
jb.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Close"))
jd.dispose();
}
});
jd.getContentPane().add(jb, BorderLayout.SOUTH);
jd.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
jd.pack();
return jd;
}
}
Not exactly sure what's happening, but one solution is to use a SwingUtilities.invokeLater():
#Override
public void focusGained(FocusEvent e)
{
noFocus.requestFocusInWindow();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createDialog().setVisible(true);
}
});
}
This will allow the text field to get focus properly before the dialog is made visible.
How can I code a button that, when clicked, closes the current JFrame and opens a new one?
This is what I have so far, but the old frame stays open:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
practise1 s = new practise1();
s.setVisible(true);
}
I have tried using .close() after the first { but it gives me an error.
If you plan on using the originial JFrame later, use setVisible(false) on the original JFrame. If you plan on closing the first JFrame and never reusing it, you can use dispose().
public void actionPerformed(ActionEvent e)
{
if(e.getSource () == button)
{
test = new JFrame();
test.setSize(300,300);
test.setVisible (true);
this.dispose();
}
}
Dispose AFTER creating the new Frame.
Thanks for the help everyone. I got it working using the this.dispose(); method
Lets say current Frame is FirstFrame
and clicking on JButton goes to NewFrame
import javax.swing.*;
public class FirstFrame extends Jframe implements ActionListener{
JButton button;
public FirstFrame(){
setVisible(true);
setSize(500,500);
button=new JButton("Click me");
button.addActionListner(this);
add(button);
}
public static void main(String[] args)
{
new FirstFrame();
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==button)
{
NewFrame nf=new NewFrame(); // Clicking on the Button will OPEN new Frame in NewFrame.java file
dispose(); //this method will close the FirstFrame
}
}
}
you just put this in your code :
(the exemple here i JButton to do this with the ActionPerformed method)
/**********************************************************************/
private void openBTNActionPerformed(java.awt.event.ActionEvent evt) {
dispose();
FrameTarget t = new FrameTaregt();
t.setVisible(true);
//set the size : 1250 pixels de width and 720 pixels de height
t.setSize(1250, 720);
//make the frame in the center wuth this
t.setLocationRelativeTo(null);
t.setResizable(true);
}
I have a java application, want to close the GUI with confirmation window to close the application
for example:-
frmViperManufacturingRecord.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frmViperManufacturingRecord.addWindowListener( new WindowAdapter(){
public void windowClosing(WindowEvent e){
JFrame frame = (JFrame)e.getSource();
int result = JOptionPane.showConfirmDialog(frame, "Are you sure you want to close the application?", "Please Confirm",JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
This is working fine, when I press the window close (x) button, but I want to bring this event to a button to perform the action 'On Click', since I am newbie finding difficulties to bring it inside the 'actionPerformed'
So far I have tried the code below and it didn't work...
//close window button
JButton btnCloseWindow = new JButton("Close Window");
btnCloseWindow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//frmViperManufacturingRecord.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frmViperManufacturingRecord.dispose();
//System.exit(0);
JFrame frame = (JFrame)e.getSource();
int result = JOptionPane.showConfirmDialog(frame, "Are you sure you want to close the application?", "Please Confirm",JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
Please give me some directions on this, thanks
Change this:
if (result == JOptionPane.YES_OPTION)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
to
if (result == JOptionPane.YES_OPTION)
System.exit(0);
}
frame.setDefaultCloseOperation is what happens when someone clicks the 'x' to close the window. Every other way to exit is controlled by you. The best way is to have your window closing listener and action listener call the same method that will pop up the dialog and call System.exit(0) if the user wants to exit. This will also help you with cleanup operations.
Sample code:
public class Test extends JPanel implements WindowListener {
public Test() {
setLayout(new BorderLayout());
add(new JLabel("This is a test."), BorderLayout.CENTER);
JButton b = new JButton("Exit");
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
exit();
}
});
add(b, BorderLayout.SOUTH);
}
public static void main(String[] args) throws Exception {
JFrame f = new JFrame();
Test t = new Test();
f.add(t, BorderLayout.CENTER);
f.addWindowListener(t);
f.pack();
f.setVisible(true);
}
public void windowClosing(WindowEvent e) {
exit();
}
private void exit() {
System.exit(0);
}
}
You can try:
if (result == JOptionPane.YES_OPTION){
frame.dispose();
}
Also note CastException on the line 122.
Instead of
JFrame frame = (JFrame)e.getSource();
change to:
JFrame frame = new JFrame();
if still not working then try
frame.setVisible(false);
frame.dispose();
in if(result == JOptionPane.YES_OPTION){} block
Could you please help me on this one? I have a JDialog with some textfields, checkboxes and buttons. I want that when the frame is not focused anymore, to disappear. So I added a focus listener to the JDialog and when the focus is lost, I call dialog.setVisible(false);. The problem is that if I click on the checkbox,textfield or button, the frame loses it's focus and disappears. How could I keep it focused until the user clicks outside it's area?
EDIT : The "frame" I am referring to is a JDialog. I don't use a Frame nor a JFrame. All the components are placed on the JDialog. I want it to hide when not focused, but keep it focused until the user clicks outside it's area.
Seems like you had added the wrong Listener, what you should be adding is addWindowFocusListener(...), see this small sample program, is this what you want to happen :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogFocus
{
private JFrame frame;
private MyDialog myDialog;
public DialogFocus()
{
}
private void createAndDisplayGUI()
{
frame = new JFrame("JFRAME");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
myDialog = new MyDialog(frame, "My Dialog", false);
JButton showButton = new JButton("SHOW DIALOG");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (!(myDialog.isShowing()))
myDialog.setVisible(true);
}
});
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(300, 300);
frame.setVisible(true);
}
public static void main(String\u005B\u005D args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new DialogFocus().createAndDisplayGUI();
}
});
}
}
class MyDialog extends JDialog
{
private WindowFocusListener windowFocusListener;
public MyDialog(JFrame frame, String title, boolean isModal)
{
setTitle(title);
setModal(isModal);
JPanel contentPane = new JPanel();
JTextField tfield = new JTextField(10);
JComboBox cbox = new JComboBox();
cbox.addItem("One");
cbox.addItem("Two");
cbox.addItem("Three");
contentPane.add(tfield);
contentPane.add(cbox);
windowFocusListener = new WindowFocusListener()
{
public void windowGainedFocus(WindowEvent we)
{
}
public void windowLostFocus(WindowEvent we)
{
setVisible(false);
}
};
addWindowFocusListener(windowFocusListener);
add(contentPane);
pack();
}
}
Make the dialog modal, then the user cannot click on the frame.
Check the FocusEvent
it has public Component getOppositeComponent(). If the opposite component is child component of the JDialog don't hide the dialog.
A typical way to use JFileChooser includes checking whether user clicked OK, like in this code:
private void addModelButtonMouseClicked(java.awt.event.MouseEvent evt) {
JFileChooser modelChooser = new JFileChooser();
if(modelChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION ){
File selectedFile = modelChooser.getSelectedFile();
if(verifyModelFile(selectedFile)){
MetModel newModel;
newModel = parser.parse(selectedFile, editedCollection.getDirectory() );
this.editedCollection.addModel(newModel);
this.modelListUpdate();
}
}
}
I tried to mimic this behavior in my own window inheriting JFrame. I thought that this way of handling forms is more convenient than passing collection that is to be edited to the new form. But I have realized that if I want to have a method in my JFrame returning something like exit status of it I need to make it wait for user clicking OK or Cancel without freezing the form/dialog window.
So, how does showOpenDialog() work? When I tried to inspect the implementation, I found only one line methods with note "Compiled code".
I tried to mimic this behavior in my own window inheriting JFrame.
JFrame is not a modal or 'blocking' component. Use a modal JDialog or JOptionPane instead.
E.G.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
/** Typical output:
[JTree, colors, violet]
User cancelled
[JTree, food, bananas]
Press any key to continue . . .
*/
class ConfirmDialog extends JDialog {
public static final int OK_OPTION = 0;
public static final int CANCEL_OPTION = 1;
private int result = -1;
JPanel content;
public ConfirmDialog(Frame parent) {
super(parent,true);
JPanel gui = new JPanel(new BorderLayout(3,3));
gui.setBorder(new EmptyBorder(5,5,5,5));
content = new JPanel(new BorderLayout());
gui.add(content, BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout(4));
gui.add(buttons, BorderLayout.SOUTH);
JButton ok = new JButton("OK");
buttons.add(ok);
ok.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
result = OK_OPTION;
setVisible(false);
}
});
JButton cancel = new JButton("Cancel");
buttons.add(cancel);
cancel.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
result = CANCEL_OPTION;
setVisible(false);
}
});
setContentPane(gui);
}
public int showConfirmDialog(JComponent child, String title) {
setTitle(title);
content.removeAll();
content.add(child, BorderLayout.CENTER);
pack();
setLocationRelativeTo(getParent());
setVisible(true);
return result;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Test ConfirmDialog");
final ConfirmDialog dialog = new ConfirmDialog(f);
final JTree tree = new JTree();
tree.setVisibleRowCount(5);
final JScrollPane treeScroll = new JScrollPane(tree);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton b = new JButton("Choose Tree Item");
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int result = dialog.showConfirmDialog(
treeScroll, "Choose an item");
if (result==ConfirmDialog.OK_OPTION) {
System.out.println(tree.getSelectionPath());
} else {
System.out.println("User cancelled");
}
}
});
JPanel p = new JPanel(new BorderLayout());
p.add(b);
p.setBorder(new EmptyBorder(50,50,50,50));
f.setContentPane(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}
I guess you wait for the user to click some button by constantly checking what button is pressed.
"I need to make it wait for user clicking OK or Cancel without freezing the form/dialog window."
May be you should use evens to get notified, when the user clicks on something, not waiting for them to press the button - maybe there is some OnWindowExit event?
Or maybe something like this:
MyPanel panel = new MyPanel(...);
int answer = JOptionPane.showConfirmDialog(
parentComponent, panel, title, JOptionPane.YES_NO_CANCEL,
JOptionPane.PLAIN_MESSAGE );
if (answer == JOptionPane.YES_OPTION)
{
// do stuff with the panel
}
Otherwise you might see how to handle window events, especially windowClosing(WindowEvent) here