1

I'm beginning with GUI and listeners. I want to choose and set file from pc into the "File zvolenysubor" in class Hlavna by another class implementing ActionListener. I can choose file in the listener's actionPerformed method and set it into "File subor" but I fail in saving it into the "File zvolenysubor" in my main (and all of my ideas how to do it failed too). What should I change/add there please?

Here are my classes:

public class Hlavna {      
    public static void main(String[] args) {
        File zvolenysubor = null;
        JFrame frame = new JFrame("ABCDE");
        JButton vybersuboru = new JButton("vyber");
        vybersuboru.setBounds(220, 15, 200, 20);


        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(640, 480);
        frame.add(vybersuboru);
        frame.setLayout(null);

        VyberListener list1 = new VyberListener(zvolenysubor);
        vybersuboru.addActionListener(list1);
        vybersuboru.setText("vyber subor");
    }
}


public class VyberListener implements ActionListener {
    private File subor;

    public VyberListener(File subor){
        this.subor = subor;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JFileChooser chooser = new JFileChooser();
        System.out.println("lol");
        FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Images", "jpg", "gif");
        chooser.setFileFilter(filter);
        chooser.showOpenDialog(null);
        subor = chooser.getSelectedFile();
        System.out.println(subor.getAbsolutePath());        
    }   
}
Dan
  • 1,763
  • 4
  • 26
  • 40

1 Answers1

0

Not really sure what you're asking here. Java passes method arguments by value as opposed to reference, so the File parameter you're supplying to the constructor of VyberListener is only updated in the VyberListener class by the actionPerformed method, not the reference in your main method. What is it you're trying to accomplish here?

If you're trying to update "File zvolenysubor" in your main method, it may be worthwhile making your "File subor" in your VyberListener class public, so that it can be accessed by the main method.

Update To minimise the amount of chatter in the comments below, I'll try and summarise. Although Java supports pass by reference, it's actually only passing pointers by reference. Thus in your example, you pass a null object reference (subor) to your ActionListener, which is then overwritten in the actionPerformed method:

subor = chooser.getSelectedFile();

Thus your File variable "zvolenysubor" is never updated. In order to update fields in your Hlavna class, I recommend using the following "Container" pattern:

public class Hlavna {      
    public static void main(String[] args) {
        // New "FileReference" container instance
        FileReference zvolenysubor = new FileReference();
        JFrame frame = new JFrame("ABCDE");
        JButton vybersuboru = new JButton("vyber");
        vybersuboru.setBounds(220, 15, 200, 20);

        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(640, 480);
        frame.add(vybersuboru);
        frame.setLayout(null);

        VyberListener list1 = new VyberListener(zvolenysubor);
        vybersuboru.addActionListener(list1);

        // Retrieves the updated File instance
        File updatedFile = zvolenysubor.getFile();
    }
}

public class VyberListener implements ActionListener {
    private FileReference subor;

    public VyberListener(FileReference subor){
        this.subor = subor;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & GIF Images", "jpg", "gif");
        chooser.setFileFilter(filter);
        chooser.showOpenDialog(null);
        subor.setFile(chooser.getSelectedFile());       
    }   
}

// FileReference container class allows the file reference to be updated by the ActionListener
// without re-initialising the object reference
public class FileReference {
    private File _file;

    public void setFile(File file) {
        _file = file;
    }

    public File getFile() {
        return _file;
    }
}
thesheps
  • 635
  • 4
  • 11
  • Yes, that's what I am trying to do, update "File zvolenysubor" which is in main method. Is there any possibility to update it somehow in actionPerformed? – Surname Lastname Feb 08 '13 at 13:28
  • Of course you are failing, because you are passing null pointer to the VyberListener constructor. You are not passing any reference to any object! – Jarosław Jaryszew Feb 08 '13 at 13:38
  • Ah yea, that's true. So how to pass reference on that zvolenysubor into the constructor please? – Surname Lastname Feb 08 '13 at 13:43
  • Please see the following link: http://stackoverflow.com/questions/1068760/can-i-pass-parameters-by-reference-in-java In order to reference the value which is updated by by your VyberListener, first consider passing an initialised string, and making the subor field public. – thesheps Feb 08 '13 at 14:17
  • Ok, now I have initialized zvolenysubor to some default value: File zvolenysubor = new File("xxx"); and I changed File subor into public. And it still doesn't work. Isn't the File zvolenysubor passed into constructor as reference since it's object? – Surname Lastname Feb 08 '13 at 14:44
  • No. There is no pass by reference in Java. Having set your subor field as public, it should now be accessible from your main method, E.g: list1.subor. This is your only option. I have updated your question. – thesheps Feb 08 '13 at 14:50
  • Oh ok thanks much :) Btw, when i make subor public so i can access and update it from main as you said (list1.subor), how can i make that it will update just after action of choosing file from pc is performed? (this is the reason i tried to put that update into actionPerformed) – Surname Lastname Feb 08 '13 at 14:54
  • Is there a specific reason for you not including the ActionListener code in your Hlavna class, and doing away with the VyberListener class (or vice versa?) This would reduce the complexity of your code, and ensure that the file variable is always mapped according to to the result of the actionPerformed() method. – thesheps Feb 08 '13 at 15:01
  • I was just doing it with help of youtube tutorial where the guy updated JLabel this way and it worked for him. Also i thought it will be more transparent in case i will have more different listeners later. http://youtu.be/EninMWwyCf8?t=5m19s here he shows the both classes – Surname Lastname Feb 08 '13 at 15:11
  • Did the above answer help at all? It would be useful for you to accept the correct answer. – thesheps Feb 12 '13 at 08:40