Java希望某些对象是最终的

时间:2016-01-20 20:12:43

标签: java swing oop

我正在构建一个GUI应用程序,我需要来自我编写的其他类的两个对象。

GUI是用main方法调用的方法编写的,在那个方法中我初始化了我的两个对象。

基本上Eclipse告诉我它

 "Cannot refer to the non-final local variable user defined in an enclosing scope"

GUI有一个按钮,按下按钮会打开另一个窗口,用户可以输入他的登录信息。

然后在java / eclipse告诉我最终制作的一个对象的帮助下获取并处理登录信息,但是当它们最终时我不能按照我想要的方式使用它们。

我应该在哪里初始化我的对象,或者我可以做什么,我可以利用这些对象,这样它们就不是最终的。

有问题的代码:

Usermanager和Player是我说过

的问题的对象

package de.unistuttgart.iaas.icetea.gui;

import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import de.unistuttgart.iaas.icetea.player.Player;
import de.unistuttgart.iaas.icetea.user.UserManager;

@SuppressWarnings("serial")
public class ICT_mainGUI extends JFrame {
    private final JPanel panel = new JPanel();

    /**
     * Launch the application. should open a window (hopefully)
     */
    public static void main(String[] args) {

        // java eventq shit
        // TODO DONT TOUCH THIS SHIT
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ICT_mainGUI frame = new ICT_mainGUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    @SuppressWarnings("unused")
    public ICT_mainGUI() {
        // initializing needed objects
        // user manager for admin and user shit
        // player for player manipulation
        // TODO DONT TOUCH THIS EITHER

        UserManager user = new UserManager();
        Player player = new Player();

        getContentPane().setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 933, 112);
        getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

        JPanel panel_1 = new JPanel();
        panel_1.setFocusCycleRoot(true);
        panel_1.setAlignmentX(Component.RIGHT_ALIGNMENT);
        panel_1.setFocusTraversalPolicyProvider(true);
        getContentPane().add(panel_1);
        panel_1.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));

        JButton playButton = new JButton("Play");
        panel_1.add(playButton);

        JButton btnPause = new JButton("Pause");
        panel_1.add(btnPause);

        JButton btnStop = new JButton("Stop");
        panel_1.add(btnStop);

        JProgressBar progressBar = new JProgressBar();
        panel_1.add(progressBar);

        JMenuBar menuBar = new JMenuBar();
        menuBar.setBorderPainted(false);
        setJMenuBar(menuBar);
        menuBar.add(panel);

        JButton signInButton = new JButton("Anmelden");
        signInButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                        //seting up our window
                        final JFrame frame = new JFrame("Login User");
                        frame.setSize(300, 200);


                        JPanel panel = new JPanel();
                        frame.add(panel);
                        panel.setLayout(null);

                //userlabel 
                JLabel userLabel = new JLabel("User");
                userLabel.setBounds(10, 10, 80, 25);
                panel.add(userLabel);

                JTextField userText = new JTextField(20);
                userText.setBounds(100, 10, 160, 25);
                panel.add(userText);

                JLabel passwordLabel = new JLabel("Password");
                passwordLabel.setBounds(10, 40, 80, 25);
                panel.add(passwordLabel);

                JPasswordField passwordText = new JPasswordField(20);
                passwordText.setBounds(100, 40, 160, 25);
                panel.add(passwordText);

                //PASSWORDREPEAT
                JPasswordField passwordrepeat = new JPasswordField(20);
                //TODO fix orientation
                passwordrepeat.setBounds(100, 70, 160,25);
                panel.add(passwordrepeat);
                passwordrepeat.setEnabled(false);

                //passwordtextrepeat
                JLabel passwordtextrepeat = new JLabel("Repeat Password");

                //TODO fix orientation
                passwordtextrepeat.setBounds(10, 70, 80, 25);
                panel.add(passwordtextrepeat);
                passwordtextrepeat.setEnabled(false);

                JButton loginButton = new JButton("login");
                loginButton.setBounds(10, 100, 90, 25);
                panel.add(loginButton);

                JButton registerButton = new JButton("add User");
                registerButton.setBounds(180, 100, 80, 25);
                panel.add(registerButton);
                registerButton.setEnabled(false);


                frame.setVisible(true);

                //doing verification stuff

                final String username = userText.getText();
                final String password = passwordLabel.getText();

                loginButton.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {

                        user.addUser(username, password);

                        if (user.getCurrentUser().equals(username)) {
                            String stringfordialog = "Login sucessful \n Current User:\n" + user.getCurrentUser();
                            JOptionPane.showMessageDialog(frame, stringfordialog);

                        } else {

                        }

                    }
                });

            }
        });

        panel.add(signInButton);

        JButton signOutButton = new JButton("Abmelden");
        panel.add(signOutButton);

        JButton adduserButton = new JButton("AddUser");

        if (user.isAdmin()) {
            adduserButton.setEnabled(true);
        } else {
            adduserButton.setEnabled(false);
        }
        panel.add(adduserButton);

        adduserButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                JFrame adduserdialog = new JFrame("AddUser");
                adduserdialog.setSize(400, 200);
                setLocationRelativeTo(null);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            }
        });
        // TODO promote User
        JButton promoteUserButton = new JButton("Promote User");

        if (user.isAdmin()) {
            promoteUserButton.setEnabled(true);
        } else {
            promoteUserButton.setEnabled(false);
        }

        panel.add(promoteUserButton);

        JSlider volumeSlider = new JSlider();
        menuBar.add(volumeSlider);
        // close button
        JButton btnClose = new JButton("Close");
        btnClose.setHorizontalAlignment(SwingConstants.LEFT);
        menuBar.add(btnClose);
        // TODO **finished** close the window
        btnClose.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

    }

}

2 个答案:

答案 0 :(得分:4)

我之前见过这个。这就是发生的事情。

Foo bar = new Foo();
ActionListener al = new ActionListener(ActionEvent ae) {
  actopnPerformed(ActionEvent ae) {
    bar.setX(x);
  }
}

问题是动作监听器中的代码不会立即被调用,并且foo变量可能在调用bar.setX时发生了变化......它们位于两个不同的范围内。因此,为了确保ActionListener中的代码具有对其将调用setX的对象的正确引用,您需要将bar声明为final - 即它不会,不能更改。

答案 1 :(得分:2)

您的匿名内部类(侦听器)通过获取局部变量的副本来引用其封闭范围 当匿名方法返回时,您的局部变量将从stack中清除,因此它们不再存在。但是匿名类对象UserManagerPlayer引用了这些变量。这是错误的行为,所以Java不允许你这样做。

在最后它变成一个常数。所以它存储在堆中,可以安全地用在匿名类中。