2

プロジェクト内のさまざまなタイプのウィンドウごとに、異なるクラスを作成しました。たとえば、私のメインウィンドウはMainWindowのインスタンスです。プロジェクト設定ウィンドウは、ProjectSettingsWindowのインスタンスです。CustomWindowという名前のクラスも作成しました。私はそれをウィンドウと名付けたでしょうが、それは採用されています。ああ。このクラスには、初期化メソッドや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();
    }
}
4

1 に答える 1

4
  • ウィンドウを呼び出しsetLocationRelativeTo(null)た後に呼び出すpack()と、ウィンドウが中央に配置されます。
  • init()メソッドがすべてのWindowオブジェクトで呼び出されていることを確認しますか?pack()最初に電話しますか?
  • あなたはGUIクラスがJFrameの作成に向けられているように見えますが、これは間違いだと思います。プログラムの柔軟性が大幅に向上するため、JPanelsの作成に対応することをお勧めします。このようにして、GUIをJFrame、JApplet、またはJDialogで使用したり、CardLayoutの「カード」として使用したり、より大きなGUIの子JPanelとして使用したりできます。
  • 多くのウィンドウスワッピングを行うGUIは、あまりユーザーフレンドリーではないため、避けてください。
  • 継承の乱用の可能性があると思います。1つは、JFrameのメソッドの1つをオーバーライドする必要があることはめったにないため、JFrameを拡張する必要があることはめったにありません。
  • 編集1setSize(...)を無効にしているため、への呼び出しに混乱しています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 に答える