中心JFrame不适用于子类

时间:2012-06-14 22:19:19

标签: java swing jframe subclass center

对于我项目中的每种不同类型的窗口,我创建了一个不同的类。例如,我的主窗口是MainWindow的一个实例。项目设置窗口是ProjectSettingsWindow的一个实例。我还创建了一个名为CustomWindow的类。我会把它命名为Window,但是已经采用了。嘎。这个类包含我所有窗口共享的东西,比如初始化方法和JPanel。它扩展了JFrame,我的所有其他窗口类都扩展了CustomWindow。

对不起,这太长了。但是这里是SSCCE :(这是我在这里的第一个问题,所以请耐心等待)

主要课程:

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类:

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类:

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类:

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类:

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();
    }
}

1 个答案:

答案 0 :(得分:4)

  • 如果您在窗口上调用setLocationRelativeTo(null)后致电pack(),它将使窗口居中。
  • 您确定在所有Window对象上调用了init()方法吗?你是先打电话给pack()吗?
  • 您似乎将GUI类用于创建JFrame,我认为这是一个错误。您可以更好地将它们设置为创建JPanel,因为这可以为您的程序提供更大的灵活性。通过这种方式,您可以在JFrame,JApplet或JDialog中使用GUI,或者在CardLayout中使用GUI,或者在更大的GUI中使用子级JPanel,...
  • 避免执行大量窗口交换的GUI,因为它不是非常用户友好。
  • 我怀疑可能过度使用继承。首先,您很少需要扩展JFrame,因为我们需要覆盖JFrame的一种方法。
  • 修改1 您被setSize(...)的电话搞砸了,因为它使pack()无效。您几乎不应该致电setSize(...),而是让组件使用pack()设置自己的首选尺寸。

编辑2
如,

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();
}

如果你能提供帮助,你甚至不应该致电setPreferredSize(...)(kleopatra肯定会为我的代码提供帮助),但请再次让组件自行调整大小。