JFrame intercept exit on close to save data - java

I created a window and want to intercept the exit with the method windowStateChanged to save the data before the application closes. However, it doesn't appear to be saving the data before it closes. How can I correct this?
see code below:
public class InventoryMainFrame extends JFrame implements WindowStateListener{
//set up the main window - instantiate the application
private InventoryInterface inventoryInterface; //panel that contains menu choices and buttons
public InventoryMainFrame(){ //main window
setTitle("Inventory System");
setSize (500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
//setLocationRelativeTo(null); //center window on the screen
inventoryInterface = new InventoryInterface(); //set up the panel that contains menu choices and buttons
add(inventoryInterface.getMainPane()); //add that panel to this window
pack();
setVisible(true);
//display window on the screen
}
public static void main(String[] args) {
//sets up front end of inventory system , instantiate the application
InventoryMainFrame aMainWindow = new InventoryMainFrame( );
}
#Override
public void windowStateChanged(WindowEvent w) {
//intercept the window close event so that data can be saved to disk at this point
if (w.getNewState()==WindowEvent.WINDOW_CLOSED){
//save the index file
try{
inventoryInterface.getInventory().saveIndexToFile();
System.out.println("saving");
dispose(); //dispose the frame
}
catch(IOException io){
JOptionPane.showMessageDialog(null,io.getMessage());
}
}
}
}

You should try registering a WindowAdapter and override its windowClosing method. For more information, see How to Write Window Listeners.

Related

Java Swing : creating frame in ActionPerformed() of different class

I have first frame containing a button. On pressing the button I invoke actionPerformed() method of different class.
JButton compress = new JButton("Submit");
compress.addActionListener(new Action1(inp,out,frame1)); // inp,out are textboxes and frame1 is 1st frame containing textboxes and JButton
In actionPerformed() of class Action1. I have created another frame there as follows
static class Action1 implements ActionListener {
JTextField input_path,out_path;
JFrame prev;
public Action1(JTextField inp,JTextField out,JFrame jf)
{
input_path = inp;
out_path = out;
prev = jf;
}
public void actionPerformed (ActionEvent e) {
prev.dispose();
try{
drawFrame();
// launch the compression job
launchJob(input_path.getText(),out_path.getText());
}
catch(IOException io){
io.printStackTrace();
}
}
public void drawFrame()
{
JFrame frame2 = new JFrame("New Frame");
JPanel panel = new JPanel();
frame2.setSize(400,300);
frame2.setLocation(500, 300);
JLabel label = new JLabel(" in Progress...");
panel.add(label);
frame2.add(panel);
frame2.setVisible(true);
}
}
But in actionPerformed(), the contents of the frame2 are getting visible after method launchJob() is executed. I want to display(make visible) content of frame2 before my function launchJob() starts executing. Can you plz suggest where im going wrong or some alternative. Thank you.
I have just verified that your frame is being set visible before your method launchJob() is called.
Consider adding some print statements to debug, for example, at the end of the drawFrame() method , add the following code:
frame2.setVisible(true);
System.out.println("frame visible");
Do the same at the start of the launch job method:
System.out.println("doing launch job");
You will see that the output is:
frame visible
doing launch job
This verifies that the JFrame is in fact being made visible before your launch job method.

Java Swing open form on button click

I am developing a card flip flop game in java Swing(using java swing for 1st time). I am using netbeans, I have a menu like new game.. I want that when the user clicks new game button then the game starts. But i dont know how to do this, like when user clicks button , then in event handling action function,is it like this?
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JFrame myframe = new JFrame();
//and the game functionality here
}
You are doing the right thing if you want to have a new window open upon click a button. In your sample code, you need to make the new frame visible.
public class NewGame {
public static void main(String[] args) {
JFrame frame = new JFrame("Start up frame");
JButton newGameButton = new JButton("New Game");
frame.setLayout(new FlowLayout());
frame.add(newGameButton);
frame.setVisible(true);
newGameButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFrame newGameWindow = new JFrame("A new game!");
newGameWindow.setVisible(true);
newGameWindow.add(new JLabel("Customize your game ui in the new window!"));
newGameWindow.pack();
}
});
frame.pack();
}
}

Disble the Maximize button in JFrame

My JFrame opens in a minimized Mode but it can be maximized.
I want to disable the maximize icon so that user cannot maximize the frame and can see it only in the minimized or default mode.
Is it possible?
Use frame.setResizable(false). It disables the maximize button but let the the 'close' and 'minimize' buttons active.
Use this in your code, try using JDialog instead of JFrame for main window.
frame.setResizeable(false);
there is no direct way to remove the maximize button off the
Resizable JFrame as it is created by Windows and it is not painted
using Swing so U can’t touch this.
so you can replace JFrame with JDialog or remove the title bar and implement customized title bar.
You can disable it by using frame.setResizeable(false); or you can remove it completely by using following code
public class Test extends JDialog {
public Test(JFrame frame, String str) {
super(frame, str);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
});
}
public static void main(String[] args) {
try {
Test myFrame = new Test(new JFrame(), "Removing maximize button");
JPanel panel = new JPanel();
panel.setSize(100, 100);
myFrame.add(panel);
myFrame.setSize(100, 100);
myFrame.setVisible(true);
} catch (IllegalArgumentException e) {
System.exit(0);
}
} }

Using repaint() method properly

I have a button that when pressed calls a changecolor() method in a different class where some drawing is done. The button listener works fine and I see from some logging that the color was in fact changed but my drawing is not updated. This is my current implementation:
(This method is called when a button is clicked)
public void changeWarningLightColor(){
System.out.println("change color method called");
if(warningLights.equals(Color.GREEN)){
warningLights=Color.RED;
System.out.println(warningLights);
repaint();
}
else{
warningLights=Color.GREEN;
repaint();
}
}
and my drawing is created in the same file in the above method as follows:
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawSomething();
//draw a bunch of lines
}
My question is what is the proper way to call repaint() in order to actually update the drawing? Do I need to somehow call g.repaint() or do something different?
Separate class where the frame is created:
public class MainWindow extends JFrame {
public MainWindow(){
JPanel Window = new JPanel();
JPanel LeftSidePanel = new JPanel();
LeftSidePanel.setLayout(new BorderLayout());
LeftSidePanel.add(new DrawStatus(),BorderLayout.CENTER); //where the drawing is added
Window.setLayout(new BoxLayout(Window,0));
Window.add(LeftSidePanel);
add(Window);
}
public static void main(String[] args) {
//main method for showing the frame we created with the panels, and circles inside it
MainWindow frame = new MainWindow();
frame.setSize((int) (.75*Toolkit.getDefaultToolkit().getScreenSize().getWidth()),(int) (.75*Toolkit.getDefaultToolkit().getScreenSize().getHeight()));
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.setTitle("DVPWS v1.0");
frame.setResizable(false);
MenuBar menu = new MenuBar();
frame.setJMenuBar(menu);
frame.setVisible(true);
}
}
If you are using a Jframe (most likely are) do
yourFrame.repaint();
Optionally
yourPanel.repaint();
In this case you could do
public MainWindow mw = new MainWindow();
mw.repaint();
If that doesnt work(i had a similar problem) than your going to have to make an instance of JFrame instead of extending it.

JPanels and handling events between them

I'm creating a GUI which has the following panels:
The Main frame which holds all the panels in the program:
public class Main extends JFrame {
private Signup signupForm;
private Login login;
private UserScreen user;
private JPanel cards;
private CardLayout cl;
private static final int INNER_FRAME_WIDTH=800;
private static final int INNER_FRAME_HEIGHT=800;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, INNER_FRAME_HEIGHT, INNER_FRAME_WIDTH);
getContentPane().setLayout(new GridLayout(0, 1, 0, 0));
cards = new JPanel();
getContentPane().add(cards);
cl = new CardLayout();
cards.setLayout(cl);
login = new Login();
cards.add(login,"login");
signupForm = new Signup();
cards.add(signupForm,"signup");
ActionListener listen = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try{
//check for a user with the parameters from userName and password fields . On success create a UserScreen for the current user.
//This means that you need to send the User object to the UserScreen c'tor. It should look something like this. Might need to change UserScreen accordingly.
user = new UserScreen();
cards.add(user,"user");
cl.show(cards,"user");
}
catch (Exception exception){ //TODO: Change to exception thrown from Client constructor
//TODO: Have the exception popup the relevant screen.
}
}
};
login.loginBtn.addActionListener(listen); << Example of setting a button's actionListener from Main.
setLoginListeners();
setSignupListeners();
}
}
A Login panel - This is the screen you encounter when you open the program.
A Signup panel - You get to this screen when pressing a 'signup' button in the login panel.
A User's screen - A screen that display's a user's info.
I've encountered an issue which I'm not sure how to handle:
After clicking the 'Login' button in the Login panel, I want to switch to the new User's screen (UserScreen object).
Since the class Login doesn't have access to the UserScreen object (only the Main frame does), I had to set the button's actionListener from the Main class which seemed like a terrible solution (since it required me to give the Main access to many fields from the Login panel so it can check if the user with the given username and password exists etc). Is there no better way?
Is there a better solution than the one I've got?
You should implement the model-view-controller pattern, the interaction between different views should always be through a controller.
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Categories