Basically I have a JFrame that opens a JDialog.
The problem I'm facing is when I attempt to do a right click on the taskbar -> close window in Windows OS
The JDialog would be 'blocking' the closing event.
I would want to close the application even if the JDialog is shown but at the same time blocking any input into the parent frame.
Edit: As a norm, dialog boxes are made to block the output but as I have mention in the comment below :
Problem lies when users need to close the application but when with a
few dialog box on screen. It requires them to close all to them before
being able to close the entire application. It would be better if only
selected critical dialog boxes blocks the closing event but not those
trivial ones
Main class
public class Main {
private Frame frmMain;
public static void main(String[] args) {
new Main();
}
public Main(){
initialize stuff..
frmMain.setVisible(true);
Message msg = MessageFrame.openDialog(frmMain);
...
}
MessageFrame class
public class MessageFrame extends JDialog {
private Message message;
public static void openDialog(Frame frame){
return new MessageFrame(frame).message;
}
private MessageFrame(Frame frame){
super(frame);
setModalityType(ModalityType.APPLICATION_MODAL);
...
setVisible(true);
}
Related
I'm relatively new to Java Swing in general and decided to use Intellij's GUI Designer. For those not familiar with it, Intellij creates 2 files for each GUI "screen". One is the "design" in the form of a .form file where you drag and drop UI components, and one is the "controller".
Anyway, I'm doing a 5-step questionnaire implemented on Java Swing. The first part asks the user what is their favourite fruit, and when a choice button is clicked, the choice is saved and the next JFrame appears with the next question and so on. JFrame1 transitioning to JFrame2 worked fine, and all UI components were shown. However, when I tried to transition from JFrame2 to JFrame3, JFrame3 showed up blank instead.
I've tried to call .pack() before setVisible(true), and then calling .toFront() after that, but that didn't help.
Below shows a section of my code. JFrame1, 2, and 3 all use the same exact code in its constructors and calling of the next JFrame. JFrame1 only differs by a single line which will be stated later in the code.
JFrame1.java
public class Frame1 extends JFrame {
private JPanel mainPanel;
private JLabel narrationLabel;
private JButton option1_btn;
private JButton option2_btn;
private JButton option3_btn;
public Frame1()
{
setTitle("Questionnaire");
setSize(1000, 1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Frame2 nextScreen = new Frame2 (); //declare the next screen to show
add(mainPanel); //this is only for the first starting JFrame
//JFrame2 and JFrame3 do not have this
//repeat this for buttons option2_btn and option3_btn
option1_btn.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
//swap screens to the next main filler selection screen
mainPanel.setVisible(false);
nextScreen.pack();
add(nextScreen.getPanel());
nextScreen.getPanel().setVisible(true);
}
});
}
public JPanel getPanel()
{
return mainPanel;
}
}
Main.java
public class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame1 frame1 = new JFrame1(); //create start screen GUI
frame1.setVisible(true); //display GUI
}
});
}
}
My hunch tells me it might a concurrency issue, but I'm not sure if I am right, or where is the issue and how to resolve it. If a .form file is needed, I would gladly upload the code for it. Any help appreciated.
I need to perform an action after the JFrame is closed and I have this part of code for it, but this doesn't work.
Could anyone please advise what should be change here?
private void changeDefaults(){
Thread changeDefaultsThread = new Thread(new Runnable(){
public void run(){
Change ch = new Change();
ch.setVisible(true);
ch.setListeners();
ch.defaultInput();
while(ch.isActive()){
System.out.println("active");
}
updateDefaults();
}
});
changeDefaultsThread.start();
}
Change is the JFrame I am opening for another action.
You can add listener to your JFrame
frame.addWindowListener (new java.awt.event.WindowAdapter)
and override the windowClosing
#Override
public void windowClosing
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
//do something
}
});
I'm surprised no one has mentioned the simplest solution: don't use a JFrame. The best tool for this behavior -- displaying a child window and doing something immediately after it has closed -- is to use a modal dialog window such as a JDialog or JOptionPane. The JDialog set up code is very similar to that of the JFrame, with an exception being that it uses different constructors, and should have the parent window passed into it, and it uses a subset of the default close operations.
If you use a modal dialog, then program flow is halted in the calling code immediately after the dialog has been displayed (think of how a JOptionPane operates), and then immediately resumes from the spot after calling setVisible(true) on the dialog once the dialog has been closed.
The only bugaboo is that if you don't want modal behavior -- if you don't want the parent/calling window to be disabled while the child window is displayed -- then you'll have to use a non-modal JDialog window with a WindowListener.
If you want to perform an action when closing a JFrame, you just need to attach a WindowListener (extending WindowAdapter so that you do not need to implement all WindowListener methods):
import javax.swing.*;
public class AfterJFrameClose {
public static void main(String[] args) {
JFrame frame = new JFrame("My frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
System.out.println("Frame closing");
}
});
}
}
Instead of the System.out.println, just write the code you want to have executed.
Update: If you want to access another frame, you either should pass it as a parameter as suggested above or you can also iterate through active frames using something like this:
Frame[] frames = Frame.getFrames();
for (Frame frame: frames) {
System.out.println(frame.getTitle());
}
I am very new to Java Swing and I am working on a login frame with swing that works like this.
After I login successfully in a frame, another new frame is opened while the login frame goes to invisible.
What I am trying to do is that when i close the another frame (after login frame) I want the previous login frame to show again from invisible to visible. please let me know how to do this..:)
Suppose your previous frame is myPreviousFrame
just write myPreviousFrame.setVisible(true); when you want to make visible.
Example:
currentFrame.dispose();
myPreviousFrame.setVisible(true);
Note: if you write code System.exit(0) it will close (terminate) your application. When your application goes terminate you can not make login frame as visible. You need to restart your application. So you need to write dispose().
UPDATED:
I suppose you have a method exitForm() which invokes when you click the Close (X).
Example:
private void exitForm(java.awt.event.WindowEvent evt) {
//System.exit(0); which was used
// to fullfill your requirement you need to write below code
this.dispose();// here [this] keyword means your current frame
//OR simply you can use this.setVisible(false); instead of this.dispose();
myPreviousFrame.setVisible(true); // this will displays your login frame
}
u may try like this:
public class jFrame1 extends javax.swing.JFrame{
// ur code
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jFrame2 f2 = new jFrame2(this);
f2.setVisible(true);
this.setVisible(false);
}
}
public class jFrame2 extends javax.swing.JFrame{
// ur code
private JFrame frame;
public jFrame2(JFrame frame) {
this.frame = frame;
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
this.frame.setVisible(true);
this.setVisible(false);
this.dispose();
}
// so on
}
Here i am just considering two frames and at present you are at second frame and wanna go back to first frame.
public class previous_action implements ActionListener{
public void actionPerformed(ActionEvent t){
Movieticket m;
m=new Movieticket();
m.display();
}
}
Here previous action is a class which will take you back to previous frame.Button frame is a class which sets frame where we are at present.Movie ticket is a public class containing display function which sets frame when the application started that is the first frame.
when the button is clicked it will take you to previous frame.
I am trying to make a simple GUI word dragging game and the way I structured the code is that I have a Driver class that sets up the main JFrame and a JPanel where the words are to be contained in and a JButton that prompts a Popup class to ask for a new word to add. and then creates a WordBox. My problem seems to arise from the fact that the Popup class is a sub-class (I think thats the correct term) and so it seems that there seems to be an extra Popup class as a layer between the Driver and the actual Popup with the WordBox. I know its confusing, but here is some of the code:
public class Popup extends JFrame implements ActionListener {
JLabel lblPrompt;
JTextField txtWord;
JButton btnOK;
BoxWord w;
static BoxWord word;
public Popup(){
//window formatting was here
btnOK.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e){
w = new BoxWord(txtWord.getText());
//word = new BoxWord("it works");
}
public static void main(String[] args) {
Popup p = new Popup();
//System.out.println(word.getWord());
}
and
public class BoxWord extends JButton {
private String s = "";
public BoxWord(String word){
this.s = word;
this.setText(word);
}
public String getWord(){
return s;
}
}
and the Driver:
public class Driver extends JFrame implements ActionListener{
JButton addWord;
JPanel panel;
int x, y;
public Driver(){
//Window formatting was here
addWord.addActionListener(this);
}
public static void main(String[] args) {
Driver d = new Driver();
}
#Override
public void actionPerformed(ActionEvent e){//make a new popup to ask for word
Popup p = new Popup();
BoxWord w = p.w;
System.out.println(w.getWord());
w.setLocation(100,100);
}
My error is (at least the begining of it. the whole thing is like 20 lines long):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at worddrag.Driver.actionPerformed(Driver.java:42)
The line 42 is the
System.out.println(w.getWord());
I feel this is a very trivial and simple problem but I cannot figure out why I keep getting the error. I essentially need to be able to access the BoxWord in the Popup actionPerformed method from the Popup main method. any and all help is appreciated. My apologies for the wall of text
w is obviously null when you try to access it.
Your problem is that you're using a JFrame where a modal dialog or JOptionPane would work better. If you used the dialog, then your calling code would wait until the dialog is no longer visible, and at that time, w would likely no longer be null.
Edit
You ask:
and can you elaborate on why JFrame will not work? Just telling me that its my problem doesnt help very much -
What? I didn't just tell you that it was the problem -- I offered a solution -- use a modal JDialog. Again, a modal dialog will freeze code flow from the calling code when it is launched, and the calling code will remain frozen until the dialog is no longer visible.
Your problem is that your attempting to use the w variable before the dialog window has had a chance to do anything with it. A JFrame does not pause the calling code's program flow, and that is causing your problem.
Edit 2
So a JFrame doesn't actually execute the code until it is closed?
No, not true at all. Look where your w is given a valid reference -- in your JFrame's button's ActionListener. So w will not receive a valid reference until the ActionListener has been called, which only will happen when the button is pressed. Your code as written tries to use w immediately before the user has had any chance to push your pop-up's buttons. If you used a modal JDialog instead, and made sure that w was set prior to closing the dialog, your code could work.
But a JDialog will do so as it gets the input?
Nope. See above.
I have a main window, that opens another window. I want to close this window and keep the main window open, but it closes the main window too.
I tried a lot of methods: setDefaultCloseOperation(), dispose(), setVisible(), but nothing worked for me.
In the main window I have this code
private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
AdaugaComanda ac = new AdaugaComanda();
ac.setVisible(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new FereastraPrincipala().setVisible(true);
}});}
and in the other window (that closes the main window when I close it) I have the following code
public class AdaugaProdus extends javax.swing.JFrame {
public AdaugaProdus() {
initComponents();
initComboBoxes();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
AdaugaProdus ad = new AdaugaProdus();
ad.setVisible(true);
}
});
}
A possible simple solution: make the secondary window a dialog such as a JDialog, not a JFrame. An application will usually have only have one JFrame open at one time. A JDialog can hold as complex a GUI as any JFrame can, and when it closes, it will never close down the JVM as a JFrame can (as you're finding out). You also have the option of making the dialog modal or not, as the need dictates.
Having said this, please understand that while new information can be shown as a dialog that is owned by the JFrame, it can also be displayed by swapping components on the JFrame via a CardLayout -- it depends on what type of information that you're trying to show.