2

对于我项目中每种不同类型的窗口,我创建了一个不同的类。例如,我的主窗口是 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);
    }
}

开始窗口类:

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
    }
}

自定义窗口类:

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
    }
}

自定义窗口事件类:

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

1 回答 1

4
  • 如果您在调用 WindowsetLocationRelativeTo(null)之后调用pack(),它将使 Window 居中。
  • 你确定你的init()方法在所有 Window 对象上都被调用了吗?你pack()先打电话?
  • 您的 GUI 类似乎是为创建 JFrame 而设计的,我认为这是一个错误。你最好让他们去创建 JPanel,因为这会给你的程序带来更大的灵活性。通过这种方式,您可以在 JFrame、JApplet 或 JDialog 中使用您的 GUI,或者作为 CardLayout 中的“卡片”,或者作为较大 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 肯定会为这段代码叮嘱我),但再次让组件自己调整大小。

于 2012-06-14T22:22:08.283 回答