Java: WindowAdapter windowClosed method not running - java

I'm currently running this in a class that extends a JFrame. When I close the window, I don't see RAN EVENT HANDLER in the console. This is not the main window, and more than one instance of this window can exist at the same time.
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
System.out.println("RAN EVENT HANDLER");
}
});
This method is inside a method called initialiseEventHandlers() which is called in the constructor, so I'm sure the code is running.
What am I doing wrong?
Thank you!
EDIT: Here's the full (summarised) code:
public class RacesWindow extends JFrame {
private JPanel mainPanel;
private JLabel lblRaceName;
private JTable races;
private DefaultTableModel racesModel;
public RacesWindow() {
this.lblRaceName = new JLabel("<html><strong>Race: " + race.toString()
+ "</strong></html>");
initialiseComponents();
this.setMinimumSize(new Dimension(500, 300));
this.setMaximumSize(new Dimension(500, 300));
initialiseEventHandlers();
formatWindow();
pack();
setVisible(true);
}
public void initialiseComponents() {
mainPanel = new JPanel(new BorderLayout());
races = new JTable();
racesModel = new DefaultTableModel();
races.setModel(racesModel);
}
public void initialiseEventHandlers() {
System.out.println("EVENTHANDLER CODE IS CALLED"); //for debugging
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
System.out.println("RAN EVENT HANDLER");
appManager.removeOpenWindow(race.toString());
}
});
}}
public void formatWindow() {
mainPanel.add(lblRaceName, BorderLayout.NORTH);
mainPanel.add(new JScrollPane(races), BorderLayout.CENTER);
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
this.add(mainPanel);
}
}

I found out I was using the wrong method: windowClosed(). I should use windowClosing()!

This should work
this.addWindowListener(new WindowListener() {
#Override
public void windowClosed(WindowEvent e) {
System.out.println("RAN EVENT HANDLER");
}
});

Add this to your constructor.
setDefaultCloseOperation(EXIT_ON_CLOSE);

The code below worked for me.
// parent class {
// constructor {
...
this.addWindowListener(new GUIFrameListener());
...
}
class GUIFrameListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.out.println("Window Closed");
}
}
} // end of parent class

Related

How to add a panel created in another class to a JFrame

I'm currently trying to create a GUI for a game. I have a JFrame with a first panel with multiples button. After a click I'm supposed to change the panel. It works I created the first class which is a Frame
public class FirstWindow extends JFrame implements ActionListener
this class contains buttons which make us change panels. For this I created the panels in different classes which extends JPanel. It worked but I am blocked because once in the second panels I still have to refer to other panels but I no longer have access to my initial JFrame.
To illustrate: This is how I switch from different JPanel. The "this" refers to the frame which I can't use in the other class
public void actionPerformed(ActionEvent e) {
if ( "START".equals(e.getActionCommand())){
this.setContentPane(new PanelHello());
this.invalidate();
this.validate();
}else if ("EXIT".equals((e.getActionCommand()))) {
this.dispose();
this.invalidate();
this.validate();
}else if (!( usernameText.getText().equals(""))){
this.setContentPane(new PanelHello());
this.invalidate();
this.validate();public void actionPerformed(ActionEvent e) {
if ( "START".equals(e.getActionCommand())){
this.setContentPane(new PanelHello());
this.invalidate();
this.validate();
}else if ("EXIT".equals((e.getActionCommand()))) {
this.dispose();
this.invalidate();
this.validate();
}else if (!( usernameText.getText().equals(""))){
this.setContentPane(new PanelHello());
this.invalidate();
this.validate();
CardLayout
The CardLayout layout manager is an extremely useful layout manager, which can be used to switch between different containers.
For me, one of its limiting factors is the need to, generally, have every container you want to switch to, instantiated and added. This can make it "heavy", in terms of memory usage and difficult when it comes to passing information between panels - as its hard abstract the workflow, not impossible, just problematic.
One of the nice features, is till automatically determine the required size of the UI based all the other containers.
See How to Use CardLayout
Custom navigation
One of the things I often finding myself needing to do, is have some kind none-linear progression through the UI, and needing the ability to effectively pass information back and forward to different containers.
The can be accomplished through the use the delegation, observer pattern and dependency injection.
The basic principle here is, you might have a number of navigation controllers, each one managing a particular workflow, independently of all the others. This kind of separation simplifies the needs of the application and makes it easier to move things around, should the need to be, as any one workflow isn't coupled to another.
Another aspect, which isn't demonstrated here, is the ability to return information to the navigation controller, for example, if you have a login/register workflow, the workflow could end by returning an instance of the "user" to the controller which would then be able to make determinations about which workflow they needed to go through next (admin/moderator/basic/etc)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MasterPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MasterPane extends JPanel {
private MenuPane menuPane;
public MasterPane() {
setLayout(new BorderLayout());
presentMenu();
}
protected void presentMenu() {
removeAll();
if (menuPane == null) {
menuPane = new MenuPane(new MenuPane.NavigationListener() {
#Override
public void presentRedPane(MenuPane source) {
RedPane redPane = new RedPane(new ReturnNavigationListener<RedPane>() {
#Override
public void returnFrom(RedPane source) {
presentMenu();
}
});
present(redPane);
}
#Override
public void presentGreenPane(MenuPane source) {
GreenPane greenPane = new GreenPane(new ReturnNavigationListener<GreenPane>() {
#Override
public void returnFrom(GreenPane source) {
presentMenu();
}
});
present(greenPane);
}
#Override
public void presentBluePane(MenuPane source) {
BluePane bluePane = new BluePane(new ReturnNavigationListener<BluePane>() {
#Override
public void returnFrom(BluePane source) {
presentMenu();
}
});
present(bluePane);
}
});
}
add(menuPane);
revalidate();
repaint();
}
protected void present(JPanel panel) {
removeAll();
add(panel);
revalidate();
repaint();
}
}
public class MenuPane extends JPanel {
public static interface NavigationListener {
public void presentRedPane(MenuPane source);
public void presentGreenPane(MenuPane source);
public void presentBluePane(MenuPane source);
}
private NavigationListener navigationListener;
public MenuPane(NavigationListener navigationListener) {
this.navigationListener = navigationListener;
setBorder(new EmptyBorder(16, 16, 16, 16));
setLayout(new GridBagLayout());
JButton red = new JButton("Red");
red.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getNavigationListener().presentRedPane(MenuPane.this);
}
});
JButton green = new JButton("Green");
green.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getNavigationListener().presentGreenPane(MenuPane.this);
}
});
JButton blue = new JButton("Blue");
blue.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getNavigationListener().presentBluePane(MenuPane.this);
}
});
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.BOTH;
add(red, gbc);
add(green, gbc);
add(blue, gbc);
}
protected NavigationListener getNavigationListener() {
return navigationListener;
}
}
public interface ReturnNavigationListener<T> {
public void returnFrom(T source);
}
public class RedPane extends JPanel {
private ReturnNavigationListener<RedPane> navigationListener;
public RedPane(ReturnNavigationListener<RedPane> navigationListener) {
this.navigationListener = navigationListener;
setBackground(Color.RED);
setLayout(new BorderLayout());
add(new JLabel("Roses are red", JLabel.CENTER));
JButton back = new JButton("Back");
back.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getReturnNavigationListener().returnFrom(RedPane.this);
}
});
add(back, BorderLayout.SOUTH);
}
public ReturnNavigationListener<RedPane> getReturnNavigationListener() {
return navigationListener;
}
}
public class BluePane extends JPanel {
private ReturnNavigationListener<BluePane> navigationListener;
public BluePane(ReturnNavigationListener<BluePane> navigationListener) {
this.navigationListener = navigationListener;
setBackground(Color.BLUE);
setLayout(new BorderLayout());
add(new JLabel("Violets are blue", JLabel.CENTER));
JButton back = new JButton("Back");
back.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getReturnNavigationListener().returnFrom(BluePane.this);
}
});
add(back, BorderLayout.SOUTH);
}
public ReturnNavigationListener<BluePane> getReturnNavigationListener() {
return navigationListener;
}
}
public class GreenPane extends JPanel {
private ReturnNavigationListener<GreenPane> navigationListener;
public GreenPane(ReturnNavigationListener<GreenPane> navigationListener) {
this.navigationListener = navigationListener;
setBackground(Color.GREEN);
setLayout(new BorderLayout());
add(new JLabel("Kermit is green", JLabel.CENTER));
JButton back = new JButton("Back");
back.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getReturnNavigationListener().returnFrom(GreenPane.this);
}
});
add(back, BorderLayout.SOUTH);
}
public ReturnNavigationListener<GreenPane> getReturnNavigationListener() {
return navigationListener;
}
}
}

How to close child jFrames automatically when i close the parent?

I have a parent JFrame and two 'child' JFrames in package JFrame. Imagine I open parent JFrame and then it's child JFrames - currently all 3 forms are open. Now I close parent JFrame.
What should I do to close all child frames automatically after close their parent JFrame?
Here is my code:
class Parent:
public class Parent extends JFrame {
public Parent() {
JButton child1 = new JButton("child1");
child1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Child1().setVisible(true);;
}
});
JButton child2 = new JButton("child2");
child2.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Child2().setVisible(true);
}
});
JButton closeAllJframe = new JButton("closeAllJframe");
closeAllJframe.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
this.setBounds(500, 200, 400, 200);
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
dispose();
}
});
JPanel jPanel = new JPanel();
jPanel.add(child1);
jPanel.add(child2);
jPanel.add(closeAllJframe);
this.add(jPanel);
}
#Override
public void dispose() {
super.dispose();
}
public static void main(String[] args) {
new Parent().setVisible(true);
}}
class Child1:
public class Child1 extends JFrame {
public Child1() {
this.setBounds(200, 300, 300, 200);
this.setTitle("child 1");
}}
class Child2:
public class Child2 extends JFrame {
public Child2() {
this.setBounds(200, 300, 300, 200);
this.setTitle("child 1");
}}
Add an window listener to the frame then implements the windowClosed(WindowEvent e) method Javadoc about WindowListener

UpdateComponentTreeUI changes cursor position in JTextField

when I use updateComponentTreeUI for a non-empty JTextField, the position of the cursor is moved from the end of the text to the front, as seen in the given example. Can anybody think of a reason, a fix, or has experienced this? Since I have many textfields in many different classes, a global solution without adding a Listener to every textfield would be appreciated. Here is a simple example:
import java.awt.*;
import java.awt.Dialog.*;
import java.awt.event.*;
import java.lang.reflect.*;
import javax.swing.*;
public class DialogTest {
final JFrame frame = new JFrame("DialogTest");
JDialog dlg;
public DialogTest() {
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JButton(action1), BorderLayout.NORTH);
frame.add(new JButton(action2), BorderLayout.CENTER);
frame.pack();
frame.setLocation(200, 200);
frame.setVisible(true);
}
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
new DialogTest();
}
});
} catch (InvocationTargetException | InterruptedException e1) {
}
}
private void setStuff() {
dlg = new JDialog(frame, "Dialog", ModalityType.DOCUMENT_MODAL);
dlg.getContentPane().setLayout(new BorderLayout());
dlg.getContentPane().add(new JTextField("test 123", 20), BorderLayout.NORTH);
dlg.getContentPane().add(new JTextField("Bla bla bla bla bla", 20), BorderLayout.CENTER);
dlg.getContentPane().add(new JButton(new AbstractAction("Close") {
#Override
public void actionPerformed(ActionEvent e) {
dlg.setVisible(false);
}
}), BorderLayout.SOUTH);
dlg.setLocation(250, 250);
}
final Action action1 = new AbstractAction("Dialog") {
#Override
public void actionPerformed(ActionEvent e) {
setStuff();
dlg.pack();
dlg.setVisible(true);
}
};
final Action action2 = new AbstractAction("UpdateComponentTree") {
#Override
public void actionPerformed(ActionEvent e) {
setStuff();
SwingUtilities.updateComponentTreeUI(dlg);
dlg.pack();
dlg.setVisible(true);
}
};
}

Running JUnit Tests in a Swing GUI using Swing Worker

I'm writing a GUI that is able to perform some JUnit Tests and to handle this I have used a SwingWorker.
When I start the program the GUI comes up and I click through some selections and the SwingWorker initiates and does it's part and finally outputs either a console output or file output. Then I would click through the GUI again and start another test. At this point when the program finishes it would generate the final output twice, e.g. the console output would be followed directly by an identical console output.
I am assuming this is due to the SwingWorker not terminating and "dying".
Also I am creating the SwingWorker when I click a "start" button in the GUI. Is this a bad idea and what would the proper way to do it be instead?
EDIT Added code sample
public class TestMainFrame {
private static JFrame frame;
private static JTextArea textArea;
public TestMainFrame(){
createAndShowGUI();
}
private void createAndShowGUI() {
frame = new JFrame("Test");
frame.setLayout(new BorderLayout());
JButton btn = new JButton("Test Me");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(btn.getText().equals("Test Me")){
testMe();
}
}
});
textArea = new JTextArea("This is a test pane! \n");
textArea.setEditable(false);
JScrollPane scroller = new JScrollPane(textArea);
frame.add(scroller, BorderLayout.CENTER);
frame.add(btn, BorderLayout.PAGE_END);
frame.setSize(new Dimension(300, 400));
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static void testMe(){
writeToTextArea("Button Pressed");
writeToTextArea("Starting tests");
SwingWorker<Result, Void> worker = new SwingWorker<Result, Void>() {
#Override
public Result doInBackground() {
writeToTextArea("Inside the doInBackground method of SwingWorker");
return null;
}
#Override
public void done() {
writeToTextArea("The SwingWorker has finished");
}
};
worker.execute();
}
private static void writeToTextArea(String text){
textArea.append(text + "\n");
}
(Not an answer)
This is how I ran your code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestMainFrame {
private static JFrame frame;
private static JTextArea textArea;
public TestMainFrame() {
createAndShowGUI();
}
private void createAndShowGUI() {
frame = new JFrame("Test");
frame.setLayout(new BorderLayout());
final JButton btn = new JButton("Test Me");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (btn.getText().equals("Test Me")) {
testMe();
}
}
});
textArea = new JTextArea("This is a test pane! \n");
textArea.setEditable(false);
JScrollPane scroller = new JScrollPane(textArea);
frame.add(scroller, BorderLayout.CENTER);
frame.add(btn, BorderLayout.PAGE_END);
frame.setSize(new Dimension(300, 400));
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static void testMe() {
writeToTextArea("Button Pressed");
writeToTextArea("Starting tests");
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
#Override
public Void doInBackground() {
writeToTextArea("Inside the doInBackground method of SwingWorker");
return null;
}
#Override
public void done() {
writeToTextArea("The SwingWorker has finished");
}
};
worker.execute();
}
// *** note change ***
private static void writeToTextArea(final String text) {
if (SwingUtilities.isEventDispatchThread()) {
textArea.append(text + "\n");
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text + "\n");
}
});
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
TestMainFrame testMainFrame = new TestMainFrame();
testMainFrame.createAndShowGUI();
}
});
}
}

How to fix the NullPointerException error? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
When I run my simple Java browser, I try and visit a webpage such as http://google.com and it returns the NullPointerException error from my try catch code, how would I fix this?
Frame Class:
public class Frame extends JFrame {
public EditorPane pane;
public URLBar urlbar;
public static void main(String[] args) throws Exception {
Frame frame = new Frame();
}
public Frame() throws Exception {
super("Java Browser v1.0");
JPanel mainPanel = new JPanel(new BorderLayout());
URLBar addressBar = new URLBar("Enter URL here!", pane);
EditorPane contentDisplay = new EditorPane(urlbar);
mainPanel.add(contentDisplay, BorderLayout.CENTER);
mainPanel.add(addressBar, BorderLayout.NORTH);
add(mainPanel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(700, 400);
add(new JScrollPane(mainPanel));
setVisible(true);
}
}
URLBar Class:
public class URLBar extends JTextField {
public EditorPane pane;
public URLBar(String text, EditorPane pane) {
super(text);
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
loadContent(event.getActionCommand());
}
}
);
}
public void loadContent(String userInput) {
try
{
pane.setPage(userInput);
setText(userInput);
}
catch (Exception e)
{
System.out.println("A wild exception appeared! Type: " + e);
}
}
}
EditorPane Class:
public class EditorPane extends JEditorPane {
public URLBar urlbar;
public EditorPane(URLBar urlbar) {
setEditable(false);
setVisible(true);
addHyperlinkListener(
new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent event) {
if(event.getEventType()==HyperlinkEvent.EventType.ACTIVATED) {
urlbar.loadContent(event.getURL().toString());
}
}
}
);
}
}
It looks like you forgot to init the pane member in your URLBar constructor, which means it is null when you call loadContent.
Here's a fix:
public URLBar(String text, EditorPane pane) {
super(text);
this.pane = pane; // add this
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
loadContent(event.getActionCommand());
}
}
);
}

Categories

Resources