java - 居中 JFrame 在子子类中不起作用

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

自定义窗口类:

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

最佳答案

  • 如果在窗口上调用 pack() 后调用 setLocationRelativeTo(null),它将使窗口居中。
  • 您确定您的 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 肯定会因为这段代码而困扰我),而是再次让组件自行调整大小。

关于java - 居中 JFrame 在子子类中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11042137/

相关文章:

java - 在 JTable 中命名列

java - 对于我的案例,未找到具有 URI 的 HTTP 请求的映射

java - 如何在 JavaFX TreeView 中搜索下一个 TreeItem?

Java JDBC 登录表单

java - 在 Java 中绘制二维数组

java - 指定Canvas在Swing中的位置

java - AppCompatActivity 的接口(interface)

java - 有没有其他方法可以在不使用 Java IDE 的情况下进行热交换?

java - 在不同的图形环境中查找 JFrame 标题和边框的大小

java - 在 JSP 中将 Graphics2D 显示为 JPG