2

新しい JFrame オブジェクトを作成するたびに、フレームが 0,0 の位置に表示されます。setLocationRelativeTo() を使用してウィンドウを中央に配置する方法を調べてみましたが、コンテナーで呼び出しようとしたすべてがコンパイル不能なコードとして表示されます。ここに私が使用している私のクラスの1つがあります:

package Ginfo;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;

public class EditUsers extends JFrame implements ActionListener
{
    Container EU;

    JPanel modUsers, button, output;
    JLabel user, password;
    JTextField tuser, tpassword;
    JTextArea toutput;
    JButton addAdmin, addStand, editPass, removeUser, exit;

    ObjectOutputStream oout;
    ObjectInputStream oin;

    Message m;
    ConnectInfo c;

public EditUsers (ObjectOutputStream oout2, ObjectInputStream oin2, Message m2, ConnectInfo a)
{
    super("User Modifications");
    EU = getContentPane();
    oout = oout2;
    try 
    {
        oout.reset();
    } 
    catch (IOException e)
    {
        e.printStackTrace();
    }
    oin = oin2;
    m = m2;
    c = a;

    buildUserInfoPanel();
    buildOutputPanel();
    buildButtonPanel();
    EU.add(modUsers, BorderLayout.NORTH);
    EU.add(output, BorderLayout.CENTER);
    EU.add(button, BorderLayout.SOUTH);
    pack();
    setVisible(true);

}

private void buildUserInfoPanel()
{
    modUsers = new JPanel();
    modUsers.setLayout(new GridLayout (2,2));
    user = new JLabel ("Enter the username you wish to edit: ");
    tuser = new JTextField (15);
    password = new JLabel("Enter their new password: ");
    tpassword = new JTextField(15);

    modUsers.add(user);
    modUsers.add(tuser);
    modUsers.add(password);
    modUsers.add(tpassword);
}

private void buildOutputPanel()
{
    output = new JPanel();
    toutput = new JTextArea();
    toutput.setPreferredSize(new Dimension (400,100));

    output.add(toutput);
}

private void buildButtonPanel()
{
    button = new JPanel();
    addAdmin = new JButton ("Add user as administrator");
    addStand = new JButton ("Add user as standard");
    editPass = new JButton ("Change password");
    removeUser = new JButton ("Remove user");
    exit = new JButton ("Back");

    button.add(addAdmin);
    button.add(addStand);
    button.add(editPass);
    button.add(removeUser);
    button.add(exit);

    addAdmin.addActionListener(this);
    addStand.addActionListener(this);
    editPass.addActionListener(this);
    removeUser.addActionListener(this);
    exit.addActionListener(this);
}

public void actionPerformed(ActionEvent e) 
{
    if (e.getSource() == addAdmin)
    {
        m.type = Message.ADDADMIN;
        m.main = tuser.getText();
        m.setPassword = tpassword.getText();
        m.setPermission = 1;
    }
    else if (e.getSource() == addStand)
    {
        m.type = Message.ADDSTANDARD;
        m.main = tuser.getText();
        m.setPassword = tpassword.getText();
        m.setPermission = 2;
    }
    else if (e.getSource() == editPass)
    {
        m.type = Message.CHANGEPASSWORD;
        m.main = tuser.getText();
        m.setPassword = tpassword.getText();
    }
    else if (e.getSource() == removeUser)
    {
        m.type = Message.REMOVEUSER;
        m.main = tuser.getText();
    }
    else if (e.getSource() == exit)
    {
        new WhatToDo (oout, oin, m, c);
        dispose();
        return;
    }
    try 
    {
        oout.writeObject(m);
        m = (Message)oin.readObject();
        toutput.setText(m.response);
    } 
    catch (IOException e1) 
    {
        e1.printStackTrace();
    } 
    catch (ClassNotFoundException e1) 
    {
        e1.printStackTrace();
    }
}
}

このコードを実行すると、ウィンドウは (0,0) の位置から始まります。私がやりたいのは、ウィンドウのサイズを実行中のコンピューターの解像度の 1/4 に変更し、ウィンドウの位置をリセットして、ウィンドウの中心が画面の中心になるようにすることです。解像度が 1000x1000 の場合、ウィンドウは 250x250 で、(500 - 250/2)X,(500 - 250/2)Y (左上隅) x (500 + 250/2)X, (500 + 250/2) に配置する必要があります。 )Y (右下隅)

(注意してください、プロセスが完了したときにウィンドウを開いたり閉じたりするウィンドウごとに異なるクラスを使用しているため、他のクラスがないと、これは完全にコンパイルできません。私は ObjectOutputStream、ObjectInputStream、オブジェクト I を渡しています。 Message を呼び出し、別のオブジェクトを ConnectInfo と呼びます。出力ストリームと入力ストリームはサーバーへの接続を維持するためのものです。Message は前後に送信されるシリアル化された情報であり、ConnectionInfo は本質的に Cookie 情報 (ユーザー接続、セッション情報、アクセス許可) を保持します。レベルなど)。

さて、私は持っています

package Ginfo;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;

public class EditUsers implements ActionListener
{

Container EU;

JFrame myJFrame;

JPanel modUsers, button, output;
JLabel user, password;
JTextField tuser, tpassword;
JTextArea toutput;
JButton addAdmin, addStand, editPass, removeUser, exit;

ObjectOutputStream oout;
ObjectInputStream oin;

Message m;
ConnectInfo c;

public EditUsers (ObjectOutputStream oout2, ObjectInputStream oin2, Message m2, ConnectInfo a)
{
    myJFrame = new JFrame("User Modifications");
    EU = myJFrame.getContentPane();
    oout = oout2;
    try 
    {
        oout.reset();
    } 
    catch (IOException e)
    {
        e.printStackTrace();
    }
    oin = oin2;
    m = m2;
    c = a;

    buildUserInfoPanel();
    buildOutputPanel();
    buildButtonPanel();
    EU.add(modUsers, BorderLayout.NORTH);
    EU.add(output, BorderLayout.CENTER);
    EU.add(button, BorderLayout.SOUTH);
    myJFrame.add(EU);
    myJFrame.pack();
    myJFrame.setVisible(true);

}

private void buildUserInfoPanel()
{
    modUsers = new JPanel();
    modUsers.setLayout(new GridLayout (2,2));
    user = new JLabel ("Enter the username you wish to edit: ");
    tuser = new JTextField (15);
    password = new JLabel("Enter their new password: ");
    tpassword = new JTextField(15);

    modUsers.add(user);
    modUsers.add(tuser);
    modUsers.add(password);
    modUsers.add(tpassword);
}

private void buildOutputPanel()
{
    output = new JPanel();
    toutput = new JTextArea();
    toutput.setPreferredSize(new Dimension (200,100));

    output.add(toutput);
}

private void buildButtonPanel()
{
    button = new JPanel();
    addAdmin = new JButton ("Add user as administrator");
    addStand = new JButton ("Add user as standard");
    editPass = new JButton ("Change password");
    removeUser = new JButton ("Remove user");
    exit = new JButton ("Back");

    button.add(addAdmin);
    button.add(addStand);
    button.add(editPass);
    button.add(removeUser);
    button.add(exit);

    addAdmin.addActionListener(this);
    addStand.addActionListener(this);
    editPass.addActionListener(this);
    removeUser.addActionListener(this);
    exit.addActionListener(this);
}

public void actionPerformed(ActionEvent e) 
{
    if (e.getSource() == addAdmin)
    {
        m.type = Message.ADDADMIN;
        m.main = tuser.getText();
        m.setPassword = tpassword.getText();
        m.setPermission = 1;
    }
    else if (e.getSource() == addStand)
    {
        m.type = Message.ADDSTANDARD;
        m.main = tuser.getText();
        m.setPassword = tpassword.getText();
        m.setPermission = 2;
    }
    else if (e.getSource() == editPass)
    {
        m.type = Message.CHANGEPASSWORD;
        m.main = tuser.getText();
        m.setPassword = tpassword.getText();
    }
    else if (e.getSource() == removeUser)
    {
        m.type = Message.REMOVEUSER;
        m.main = tuser.getText();
    }
    else if (e.getSource() == exit)
    {
        new WhatToDo (oout, oin, m, c);
        myJFrame.dispose();
        return;
    }
    try 
    {
        oout.writeObject(m);
        m = (Message)oin.readObject();
        toutput.setText(m.response);
    } 
    catch (IOException e1) 
    {
        e1.printStackTrace();
    } 
    catch (ClassNotFoundException e1) 
    {
        e1.printStackTrace();
    }
}
}

現在、問題は myJFrame.add(EU) にあり、「java.lang.IllegalArgumentException: コンテナーの親をそれ自体に追加しています」と表示されます。事前に助けてくれてありがとう。

4

3 に答える 3

7

試すmyJFrameObject.setLocationRelativeTo(null);

JavaDocから

  • コンポーネントがnullの場合、またはこのコンポーネントに関連付けられているGraphicsConfigurationがnullの場合、ウィンドウは画面の中央に配置されます。中心点は、GraphicsEnvironment.getCenterPointメソッドを使用して取得できます。
  • コンポーネントがnullではないが、現在表示されていない場合、ウィンドウは、このコンポーネントに関連付けられたGraphicsConfigurationによって定義されたターゲット画面の中央に配置されます。
  • コンポーネントがnullでなく、画面に表示されている場合、ウィンドウは、ウィンドウの中心がコンポーネントの中心と一致するように配置されます。

編集

この(それほど高度ではない)コンストラクターでコードをテストしたところ、希望どおりに機能しているようです(少なくともそれが私が望んでいることです)。フレームにすべての要素が含まれていることを確認し、中央揃え時に使用するサイズを確認するために、setLocationRelativeTo(null)直前に配置しました。setVisible(true)

public EditUsers() {
    super("User Modifications");
    //I removed some not GUI operations

    EU = getContentPane();

    buildUserInfoPanel();
    buildOutputPanel();
    buildButtonPanel();
    EU.add(modUsers, BorderLayout.NORTH);
    EU.add(output, BorderLayout.CENTER);
    EU.add(button, BorderLayout.SOUTH);
    pack();
    //put setLocationRelativeTo before setVisible() 
    setLocationRelativeTo(null);
    setVisible(true);
}
于 2012-06-23T13:46:56.490 に答える
5

GUIコンストラクターの最後のコード行として呼び出す必要があります

JFrame#pack();
JFrame#setLocationRelativeTo(null); // Windows OS
//or JFrame#setLocationByPlatform(true); //depends of Native OS
JFrame#setVisible(true);

別の提案

  • JFrame を拡張せず、ローカル変数、インスタンスを作成する

  • JTextAreaに PreferredSize を設定しないでください。代わりに、列と行に設定することをお勧めします

  • に設定GridLayoutするかもしれませんが、デフォルトbutton = new JPanel();で持っていますJPanelFlowLayout

編集

コード行EditUsers eu = new EditUsers();をメイン クラスに配置し、新しい GUI インスタンスを で返しJFrame、コードをラップしてInitialThreadにGUI を作成します。

   public static void main(String[] a_args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                EditUsers eu = new EditUsers();
            }
        });
    }

EDIT2

変更されたコードが返されます

ここに画像の説明を入力

コードから

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

public class EditUsers implements ActionListener {

    private JFrame myJFrame;
    private JPanel modUsers, button, output;
    private JLabel user, password;
    private JTextField tuser, tpassword;
    private JTextArea toutput;
    private JButton addAdmin, addStand, editPass, removeUser, exit;
    private ObjectOutputStream oout;
    private ObjectInputStream oin;
    //private Message m;
    //private ConnectInfo c;

    public static void main(String[] a_args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                EditUsers eu = new EditUsers();
            }
        });
    }

    public EditUsers() {
        //editUsers(oout2, oin2, m2, a);
        buildUserInfoPanel();
        buildOutputPanel();
        buildButtonPanel();
        myJFrame = new JFrame("User Modifications");
        myJrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myJFrame.add(modUsers, BorderLayout.NORTH);
        myJFrame.add(output, BorderLayout.CENTER);
        myJFrame.add(button, BorderLayout.SOUTH);
        myJFrame.pack();
        myJFrame.setLocationRelativeTo(null);
        myJFrame.setVisible(true);
    }

    /*private void editUsers(ObjectOutputStream oout2, 
          ObjectInputStream oin2, Message m2, ConnectInfo a) {
        oout = oout2;
        try {
            oout.reset();
        } catch (IOException e) {
            e.printStackTrace();
        }
        oin = oin2;
        m = m2;
        c = a;
    }*/

編集3

JTextAreaJScrollPaneにある必要があります。

于 2012-06-23T13:44:37.233 に答える
2

ウィンドウが多かれ少なかれその次元で初期化された後に呼び出されるsetLocationRelativeToべきです。

packコマンドの直後のサンプルについて。pack()コマンドによってフレームが再配置される可能性があります。

于 2012-06-23T14:14:16.893 に答える