我正在构建一个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);
}
});
}
}
答案 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中清除,因此它们不再存在。但是匿名类对象UserManager
和Player
引用了这些变量。这是错误的行为,所以Java不允许你这样做。
在最后它变成一个常数。所以它存储在堆中,可以安全地用在匿名类中。