0

私はSwingを初めて使用し、Javaの経験も限られています。GUIを作成していますが、メイン画面にアクセスするには、最初にログインが必要です。私はクラスを次のように構成しました。

クラスツリーのルート:

public class master {

static mainwindow mainWindow;
static login loginScreen;

static JFrame frame;}

正しいユーザー名とパスワードの結果は、パネルをログイン画面からメインウィンドウに切り替えるはずです。私の問題は、クラス「login」でログインアクションが処理されると、「上位」のクラスにあるため、メインウィンドウパネルまたはフレームにアクセスできないことです。

私が求めていることが明確であることを願っています。そうでない場合は、より多くのコードと詳細を使用して投稿を編集します。

4

2 に答える 2

3

オブジェクト指向の重要な概念の 1 つは、責任の分離です。

あなたの場合、Loginログインが成功した後に実行する必要があるアクションを決定するのはコンポーネントの責任ではありません(失敗したと主張することもできます)。

この場合、ログイン コンポーネントが関係者にログイン プロセスの状態を通知する何らかの方法が必要です。これは、オブザーバー パターンのようなものを使用して実現するのが最適です。

基本的に、これは、変更に反応できるある種のリスナー/コールバックがあることを意味します。

次の例では、ビューを切り替える主な手段として を使用しましたが、(Hovercraft が行ったように) ログイン フォームに を使用して、ログインが処理されたらメイン フレームをロードするCardLayoutことも簡単にできます。JDialog成功しました。

ここに画像の説明を入力

public class TestCardLogin {

    public static void main(String[] args) {
        new TestCardLogin();
    }

    public TestCardLogin() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements LoginListener {

        private MainPane mainPane;
        private LoginPane loginPane;

        public TestPane() {
            setLayout(new CardLayout());

            mainPane = new MainPane();
            loginPane = new LoginPane(this);

            add(mainPane, "MAIN");
            add(loginPane, "LOGIN");

            ((CardLayout) getLayout()).show(this, "LOGIN");

        }

        @Override
        public void loginSuccessful() {
            ((CardLayout) getLayout()).show(this, "MAIN");
        }

        @Override
        public void loginFailed() {
            JOptionPane.showMessageDialog(TestPane.this, "Login failed", "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    public class MainPane extends JPanel {

        public MainPane() {
            JLabel label = new JLabel("Welcome!");
            Font font = label.getFont();
            label.setFont(font.deriveFont(Font.BOLD, 32));
            setLayout(new GridBagLayout());
            add(label);
        }
    }

    public class LoginPane extends JPanel {

        private JTextField user;
        private JPasswordField password;
        private JButton login;
        private LoginListener loginListener;

        public LoginPane(LoginListener listener) {
            this.loginListener = listener;
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.EAST;
            add(new JLabel("User name:"), gbc);
            gbc.gridy++;
            add(new JLabel("Password:"), gbc);

            gbc.gridx++;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.WEST;

            user = new JTextField(12);
            password = new JPasswordField(12);

            add(user, gbc);
            gbc.gridy++;
            add(password, gbc);

            login = new JButton("Login");

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(login, gbc);

            login.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    boolean accept = (boolean) (((int) Math.round(Math.random() * 1)) == 0 ? true : false);
                    if (accept) {
                        loginListener.loginSuccessful();
                    } else {
                        loginListener.loginFailed();
                    }
                }
            });

        }
    }

    public interface LoginListener {

        public void loginSuccessful();

        public void loginFailed();
    }
}
于 2013-03-04T23:33:27.037 に答える
3

メソッドや変数にグローバル スコープを与えるために、現在行っている方法で静的変数やメソッドを使用しないでください。そうすると、オブジェクト指向プログラミングの利点の多くが失われるためです。

メイン クラスが必要です。おそらく、すべてを実行し、必要な場所への参照を渡すコントロール クラスと呼ぶことができます。通常、私のログイン ウィンドウは、JFrame であるメイン ウィンドウに対してモーダルな JDialog などのモーダル ダイアログです。

たとえば、次のようなもの...

public class MasterControl {
   private MainView mainView = new MainView(this);
   private LoginView loginView = new LoginView(this);

   public MasterControl() {
      loginAndStart();
   }

   private void loginAndStart() {
      JFrame frame = new JFrame("MasterControl");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainView.getMainPanel());
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);

      JDialog loginDialog = new JDialog(frame, "Log In", ModalityType.APPLICATION_MODAL);
      loginDialog.getContentPane().add(loginView.getMainPanel());
      loginDialog.pack();
      loginDialog.setLocationRelativeTo(frame);
      loginDialog.setVisible(true);

      // here extract info from loginView, ask model to validate login credentials
      // and then change main view.
   }
于 2013-03-04T23:25:56.793 に答える