2

For each of the different types of windows in my project I created a different class. For example, my main window is an instance of MainWindow. The project settings window is an instance of ProjectSettingsWindow. I also created a class named CustomWindow. I would've named it Window, but that's taken. Gah. This class contains things that all of my windows share, like an initialization method and JPanel. It extends JFrame and all of my other window classes extend CustomWindow.

Sorry this is exceedingly long. But here's the SSCCE: (this is my first question on here, so bear with me)

Main class:

package beat;

public class Main {
    public static StartWindow start = new StartWindow();

    public static void main(String[] args) {
        start.init(300, 100, "choices, choices");
        start.display();
    }

    public static void close() {
        //does other things
        System.exit(0);
    }
}

StartWindow class:

package beat;
import javax.swing.*;

public class StartWindow extends CustomWindow {
    public StartWindow() {
        eventHandler = new StartWindowEvents(this);
    }

    JButton newButton = new JButton();
    JButton loadButton = new JButton();

    //initialize
    public void initBranch() {
        initButtons();
            //other classes have a few groups to initialize, not just one   
}

    private void initButtons() {
        newButton.setText("new project");
        newButton.setSize(120,49);
        newButton.setLocation(10,10);
        newButton.addActionListener(eventHandler);

        loadButton.setText("load project");
        loadButton.setSize(120,49);
        loadButton.setLocation(164,10);
        loadButton.addActionListener(eventHandler);

        content.add(newButton);
        content.add(loadButton);
    }
}

StartWindowEvents class:

package beat;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;

public class StartWindowEvents extends CustomWindowEvents {
    public StartWindowEvents(CustomWindow w) {
        super(w);
    }

    //if a button is pressed
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == Main.start.newButton)
            newButton();
        else if (e.getSource() == Main.start.loadButton)
            loadButton();
    }

    private void newButton(){
        //do the newButton stuff
    }
    private void loadButton() {
        //do the loadButton stuff
    }
}

CustomWindow class:

package beat;
import javax.swing.*;

public class CustomWindow extends JFrame {
    JPanel content = new JPanel(null);
    CustomWindowEvents eventHandler;

    public void display() {
        //whatever you want to refresh, usually nothing
        setVisible(true);
    }

    public void init(int width, int height, String title) {
        pack();
        setVisible(false);
        setResizable(false);
        setLocationRelativeTo(null); //center on screen, but it doesnt work
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        setContentPane(content);
        addWindowListener(eventHandler);

        setSize(width, height);
        setTitle(title);

        initBranch();
    }
    public void initBranch() {
        //whatever you want to do after the window is initialized, usually  branch to groups of JComponents
    }
}

CustomWindowEvents class:

package beat;
import java.awt.event.*;
import javax.swing.JOptionPane;

public class CustomWindowEvents extends WindowAdapter implements ActionListener {
    CustomWindow source;

    public CustomWindowEvents(CustomWindow w) {
        source = w;
    }

    public void actionPerformed(ActionEvent e) {}

    public void windowClosing(WindowEvent e) {
        int i = JOptionPane.showConfirmDialog(source,
                "DONT DO IT",
                "are you sure?",
                JOptionPane.YES_NO_OPTION);
        if (i == JOptionPane.YES_OPTION)
            doClose();
    }

    public void doClose() {
        //whatever you want to do after the window is confirmed closed, usually exit the program    
    Main.close();
    }
}
tschwab
  • 1,056
  • 1
  • 12
  • 27

1 Answers1

4
  • If you call setLocationRelativeTo(null) after calling pack() on a Window, it will center the Window.
  • Are you sure that your init() method is being called on all Window objects? Are you calling pack() first?
  • You appear to have your GUI classes geared toward creating JFrames, and I think that this is a mistake. You are much better off gearing them to creating JPanels as this gives your program much greater flexibility. This way you can use your GUI in a JFrame, or a JApplet, or a JDialog, or as a "card" in a CardLayout, or as a child JPanel in a larger GUI,...
  • Avoid a GUI that does a lot of window-swapping as that's not very user friendly.
  • I suspect a potential overuse of inheritance. For one, it is rare that you need to extend JFrame as it is rare that we need to override one of JFrame's methods.
  • Edit 1 You're being messed up by your call to setSize(...) as it's nullifying the pack(). You should almost never call setSize(...) and instead let the components set their own preferred sizes with pack().

Edit 2
e.g.,

public void init(int width, int height, String title) {
  // !! pack();
  setVisible(false);
  setResizable(false);
  // !! setLocationRelativeTo(null); // center on screen, but it doesnt work
  setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
  setContentPane(content);
  addWindowListener(eventHandler);

  // !! setSize(width, height);
  setPreferredSize(new Dimension(width, height)); // !!
  pack(); // !!
  setLocationRelativeTo(null); // !!
  setTitle(title);

  initBranch();
}

You shouldn't even call setPreferredSize(...) if you can help it (kleopatra will ding me for sure for this code), but again let the components size themselves.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I added pack() before all other functions and it did not change anything. And yes, I am sure. And yes, it looks like that from what I posted, but the majority of my program is about creating the JPanel inside each JFrame. I will take that into account thanks. You might be right, but I think it is more elegant if the class containing the JPanel and all the elements is itself the window, not the window is also among the variables of the class. But that might just be me. – tschwab Jun 14 '12 at 23:06
  • 1
    this code talking about nothing, for better help sooner post an [SSCCE](http://sscce.org/) – mKorbel Jun 14 '12 at 23:10
  • @pyzaist: I can't reproduce your problem, and use of `pack()` and `setLocationRelativeTo(null)` works well for me, and should by all accounts work for you. Consider creating and posting a minimal compilable example that demonstrates your problem, an [sscce](http://sscce). – Hovercraft Full Of Eels Jun 14 '12 at 23:10
  • sorry, i had to edit my original and not respond because noobs can only answer their own question after 8 hours – tschwab Jun 14 '12 at 23:35
  • @pyzaist: actually the correct forum behavior is to edit your original question, not to answer your own question (unless you have an original answer to present). – Hovercraft Full Of Eels Jun 14 '12 at 23:39
  • @pyzaist: Please see edit above. it's your call to `setSize(...)` that's messing you up. – Hovercraft Full Of Eels Jun 14 '12 at 23:43
  • Ahhhh! Yep that's it! Before I created the CustomWindow class I had that function at the top of the pile. Then I moved it down to group it with the functions with outside variables. That makes complete sense now. Thank you! – tschwab Jun 14 '12 at 23:46
  • Surely, I can stick with the answer, excessive use of `setSize()` and improper sequence of method calling inside `CustomWindow` class. @pyzaist, always think in your mind, before you code, first you initialize a window, then you add contents to it, then you order it to pack itself according to the content, then you set it's location on the screen, only then you make it visible. Doing the other way around you making a mess of things. I hope these steps are not hard to follow :-) – nIcE cOw Jun 15 '12 at 02:32