Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local variable is accessed from within inner class: needs to be declared final error java swing [duplicate]

I am having trouble making a button that closes this swing and returns to the previous swing menu. I have tried the following...

btnBack = new JButton("Back");
btnBack.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        MainMenu gui = new MainMenu(uname);
        gui.setVisible(true);
        gui.pack();
        gui.setLocationRelativeTo(null);
        frame.setVisible(false);
        frame.dispose();
    }
});

When I try this, it's giving me the error

Local variable frame is accessed from within inner class: needs to be declared final

I have trimmed my code removing my JDBC

public class newImageViewer implements ActionListener {

    JLabel lblInstru, lblInstruVal, lblInstrumentID, lblImgnameVal, lblImgtagVal, lblImgsizeVal, lblDateVal, lblImgpathVal, lblTakenbyVal, lblNoteVal, lblImgpath, lblTakenby, lblSalary, lblImgsize, lblDate, lblS,
            lblSVal, lblNote, lblImgtag, lblImgname, imagel;
    JTextField txtDate, txtImgpath, txtTakenby, txtImgname, txtImgtag, txtImgsize, txtNote, txtInstrumentID;
    JButton btnAdd, btnUpdate, btnDelete, btnPrev, btnNext, btnBack;
    ResultSet rs;
    private ImageIcon image1;
    String imagepath, uname;
    static final String DATABASE_URL = "jdbc:mysql://localhost:3306/mysql";
    static final String USERNAME = "root";
    static final String PASSWORD = "root";

    public static void main(String[] args) {
        newImageViewer obj = new newImageViewer();
        obj.createUI();
    }

    private void createUI() {

        JFrame frame = new JFrame("Image Details");

        JPanel pnlInput = new JPanel(new GridLayout(4, 2));

        lblImgname = new JLabel("  Image Name : ");
        txtImgname = new JTextField();

        lblImgtag = new JLabel("  ImageTag : ");
        txtImgtag = new JTextField();

        lblDate = new JLabel("  Date Stamp : ");
        txtDate = new JTextField(15);

        lblImgpath = new JLabel("  Image Path : ");
        txtImgpath = new JTextField();

        lblTakenby = new JLabel("  Taken By : ");
        txtTakenby = new JTextField();

        lblImgsize = new JLabel("  Image Size : ");
        txtImgsize = new JTextField();

        lblNote = new JLabel("  Note : ");
        txtNote = new JTextField();

        lblInstrumentID = new JLabel("  Instrument ID : ");
        txtInstrumentID = new JTextField();

        pnlInput.add(lblImgname);
        pnlInput.add(txtImgname);

        pnlInput.add(lblImgtag);
        pnlInput.add(txtImgtag);

        pnlInput.add(lblImgsize);
        pnlInput.add(txtImgsize);

        pnlInput.add(lblNote);
        pnlInput.add(txtNote);

        pnlInput.add(lblDate);
        pnlInput.add(txtDate);

        pnlInput.add(lblImgpath);
        pnlInput.add(txtImgpath);

        pnlInput.add(lblTakenby);
        pnlInput.add(txtTakenby);

        pnlInput.add(lblNote);
        pnlInput.add(txtNote);

        pnlInput.add(lblInstrumentID);
        pnlInput.add(txtInstrumentID);

        JPanel pnlButton = new JPanel(new GridLayout(1, 3));

        btnAdd = new JButton("Add");
        btnAdd.addActionListener(this);

        btnUpdate = new JButton("Update");
        btnUpdate.addActionListener(this);

        btnDelete = new JButton("Delete");
        btnDelete.addActionListener(this);

        btnBack = new JButton("Back");
        btnBack.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                MainMenu gui = new MainMenu(uname);
                gui.setVisible(true);
                gui.pack();
                gui.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });

        pnlButton.add(btnAdd);
        pnlButton.add(btnUpdate);
        pnlButton.add(btnBack);
        pnlButton.add(btnDelete);

        JPanel pnlNavigate = new JPanel(new GridLayout(1, 2));
        btnPrev = new JButton(" << ");
        btnPrev.setActionCommand("Prev");
        btnPrev.addActionListener(this);

        btnNext = new JButton(" >> ");
        btnNext.setActionCommand("Next");
        btnNext.addActionListener(this);

        pnlNavigate.add(btnPrev);
        pnlNavigate.add(btnNext);

        JPanel pnlNavAns = new JPanel(new GridLayout(4, 2));

        lblImgname = new JLabel("  Image Name : ");
        lblImgnameVal = new JLabel("Val");
        lblImgtag = new JLabel("  Image Tag : ");
        lblImgtagVal = new JLabel("Val");
        lblImgsize = new JLabel("  Image Size : ");
        lblImgsizeVal = new JLabel("Val");
        lblDate = new JLabel("  Date Stamp : ");
        lblDateVal = new JLabel("Val");
        lblImgpath = new JLabel("  Image Path : ");
        lblImgpathVal = new JLabel("Val");
        lblTakenby = new JLabel("  Taken By : ");
        lblTakenbyVal = new JLabel("Val");
        lblNote = new JLabel("  Note : ");
        lblNoteVal = new JLabel("Val");
        lblInstru = new JLabel("  Instrument ID : ");
        lblInstruVal = new JLabel("Val");

        pnlNavAns.add(lblImgname);
        pnlNavAns.add(lblImgnameVal);

        pnlNavAns.add(lblImgtag);
        pnlNavAns.add(lblImgtagVal);

        pnlNavAns.add(lblImgsize);
        pnlNavAns.add(lblImgsizeVal);

        pnlNavAns.add(lblDate);
        pnlNavAns.add(lblDateVal);

        pnlNavAns.add(lblImgpath);
        pnlNavAns.add(lblImgpathVal);

        pnlNavAns.add(lblTakenby);
        pnlNavAns.add(lblTakenbyVal);

        pnlNavAns.add(lblNote);
        pnlNavAns.add(lblNoteVal);

        pnlNavAns.add(lblInstru);
        pnlNavAns.add(lblInstruVal);



        final Container cn = frame.getContentPane();
        cn.setLayout(new BoxLayout(cn, BoxLayout.Y_AXIS));

        frame.add(pnlInput);
        frame.add(pnlButton);
        frame.add(pnlNavAns);
        frame.add(pnlNavigate);

        //If this will not be written, the only frame will be closed
        // but the application will be active.
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent evt) {

        String action = evt.getActionCommand();
        if (action.equals("Add")) {
            addOperation();
        } else if (action.equals("Update")) {
            updateOperation();
        } else if (action.equals("Delete")) {
            deleteOperation();
        } else if (action.equals("Prev")) {
            preNavigation();
        } else if (action.equals("Next")) {
            nextNavigation();
        }
    }
    private void addOperation()
    private void updateOperation()
    private void deleteOperation()
    private void preNavigation()
    private void nextNavigation()
    private void populateValue()

}
like image 368
james kerr Avatar asked Dec 20 '22 23:12

james kerr


1 Answers

As noted, all you need to do is listen to your compiler and simply make the frame variable final:

final JFrame frame = new JFrame("Image Details");

An alternative solution is to make frame a non-static class field.

The reason for the problem is that you're trying to use a local variable in an anonymous inner class, and since these classes make copies of these variables, if the variable is not marked final, there's a chance that the two frame variables, the local one and the copy inside the anonymous class's object, might hold different values.


Edit
As per my comment, your question is a very common one. For details on the problem please see this possible duplicate question: Why are only final variables accessible in anonymous class?. I'm going to vote to close this question as a duplicate and encourage others to to the same so that the comments to the accepted answer get read. The comments to the answer are where the real answer is.

like image 52
Hovercraft Full Of Eels Avatar answered Feb 01 '23 23:02

Hovercraft Full Of Eels