java - 如何从不在内部类中的 ActionListener 返回值

标签 java swing actionlistener inner-classes

我是 Java 新手,也是 StackOverflow 新手,所以,如果我做错了什么,请原谅。我会立即改正!

我的问题是:如何将实现 ActionListener 的类中的变量返回到另一个类的变量中?

实现 ActionListener 的类不是内部类。

我自愿省略导入。

这里是一个例子:

File_A.java

public class Gui extends JFrame {
    private JButton myButton;
    private String path;
    some other properties...

    public Gui () {
        myButton = new JButton("Some Text");
        myButton.AddActionListener(new Pick_Something());
    }
}

File_B.java

public class Pick_Something implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        JFileChooser selectElement = new JFileChooser();
        String path;
        int status = selectElement.showOpenDialog(null);

        if (status == JFileChooser.APPROVE_OPTION)
            path = selectElement.getSelectedFile().getAbsolutePath();
        else
            path = null;
    }
}

如何在 File_A.javapath 变量中返回 File_B.javapath 变量?

我尝试编写一个返回它的方法,但该方法没有出现在所有方法的列表中,因此无法调用。我还尝试使用 Gui 扩展 Pick_Something 并使 path 受到保护,但我遇到了 StackOverflowError

有人知道我做错了什么或知道该怎么做吗?

最佳答案

我建议使用回调,Java-8 的 java.util.function 的东西为您提供用品,实际上是 Consumer<String>在这里会完美地工作。在原始类中创建您的 Consumer,并让 ActionListener 类调用其 .accept(...)方法,将信息直接从监听类传递到GUI,耦合度低。例如,如果您的 Gui 有一个名为 filePathTxtField 的 JTextField您希望填充用户选择的文件路径(由 ActionListener 获取),那么使用者可能如下所示:

Consumer<String> consumer = (String text) -> {
    filePathTxtField.setText(text);
};

这将在 Gui 类中创建,然后通过构造函数参数传递到 ActionListener 类中:

// in the Gui class's constructor
button.addActionListener(new PickSomething(consumer));  

// the PickSomething class and its constructor
class PickSomething implements ActionListener {
    private Consumer<String> consumer;

    public PickSomething(Consumer<String> consumer) {
        this.consumer = consumer;
    }

那么 actionPerformed 方法可能如下所示:

@Override
public void actionPerformed(ActionEvent e) {
    JFileChooser selectElement = new JFileChooser();
    String path;

    // get the path String and set it
    int status = selectElement.showOpenDialog(null);

    if (status == JFileChooser.APPROVE_OPTION) {
        path = selectElement.getSelectedFile().getAbsolutePath();
    } else {
        path = null;
    }

    // pass the path String into the Gui by calling the call-back method, passing it in
    consumer.accept(path);
}

整个事情可能看起来像:

import java.util.function.Consumer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class Gui extends JPanel {
    private JTextField filePathTxtField = new JTextField(45);
    private int foo = 0;

    public Gui() {
        filePathTxtField.setFocusable(false);
        add(filePathTxtField);

        JButton button = new JButton("Get File Path");
        Consumer<String> consumer = (String text) -> {
            filePathTxtField.setText(text);
        };
        button.addActionListener(new PickSomething(consumer));
        add(button);
    }

    private static void createAndShowGui() {
        Gui mainPanel = new Gui();

        JFrame frame = new JFrame("Gui");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.function.Consumer;
import javax.swing.JFileChooser;

public class PickSomething implements ActionListener {
    private Consumer<String> consumer;

    public PickSomething(Consumer<String> consumer) {
        this.consumer = consumer;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JFileChooser selectElement = new JFileChooser();
        String path;
        int status = selectElement.showOpenDialog(null);

        if (status == JFileChooser.APPROVE_OPTION) {
            path = selectElement.getSelectedFile().getAbsolutePath();
        } else {
            path = null;
        }
        consumer.accept(path);
    }
}   

关于java - 如何从不在内部类中的 ActionListener 返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53926198/

相关文章:

java - 如何自定义ActionEvent的事件源?

java - 在Java中自动省略一个字符串

java - 在游戏开始前添加菜单

Java 没有绘制所需的图形

java - 编译器自动机,我如何制作这个图以使线条不会相交?

java - 如何在 ActionListener 中访问此变量?

java - 追加文本文件

java - apache.commons.fileupload 抛出 MalformedStreamException

java - 如何从文件读取并添加到对象数据?

java - 获取 ArrayList 元素平均值的最短形式