简体   繁体   English

Java ActionListener将变量返回到包含ActionListener的方法

[英]Java ActionListener Return Variable To Method That Contains ActionListener

I have a method like so, which is given an array of JButton and returns their text whenever they are pressed: 我有一个像这样的方法,该方法被赋予JButton数组,并在每次按下它们时返回其文本:

public static String foo(JButton[] buttons) {
    for (JButton i : buttons) {
        i.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                return i.getText();
            }
        });
    }
}

But, of course, this code will not compile because I am returning a variable to a null method. 但是,当然,此代码不会编译,因为我将变量返回给null方法。 So, how would I have i.getText() return its output too the foo() method? 那么,我如何让i.getText()返回其输出foo()方法?


Edit , all of the code: 编辑 ,所有代码:

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class JCustomFrame {
    public static void showMessageFrame(String title, String message,
            String[] textOnButtons, ImageIcon icon) {
        final JFrame frame = new JFrame();
        JPanel panel = new JPanel();

        panel.setLayout(new GridBagLayout());
        panel.setBackground(Color.WHITE);

        GridBagConstraints c = new GridBagConstraints();
        c.anchor = GridBagConstraints.EAST;
        c.fill = GridBagConstraints.RELATIVE;
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(5, 5, 5, 5);

        JLabel messageLabel = new JLabel(message);
        messageLabel.setFont(messageLabel.getFont().deriveFont(16.0f));

        panel.add(messageLabel, c);

        c.gridy = 1;
        c.gridx = 0;
        for (int i = 0; i < textOnButtons.length; i++) {
            JButton button = new JButton(textOnButtons[i]);
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    return ((JButton) arg0.getSource()).getText();
                    frame.dispose();
                }
            });
            button.setFont(button.getFont().deriveFont(16.0f));
            panel.add(button, c);
            c.gridx++;
        }

        if (icon == null) {
            frame.setIconImage(new BufferedImage(1, 1,
                    BufferedImage.TYPE_INT_ARGB_PRE));
        } else {
            frame.setIconImage(icon.getImage());
        }
        frame.add(panel);
        frame.setTitle(title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.pack();
    }

    public static void main(String[] args) {
        JCustomFrame.showMessageFrame("Test Frame",
                "Do you really want to do this?", new String[] { "Hell No",
                        "Sure, Why Not" }, null);
    }
}

This statement doesn't make sense: 这句话没有道理:

So, how would I have i.getText() return its output too the foo() method? 那么,我如何让i.getText()也返回其输出foo()方法?

The method foo() is no longer running after the ActionListeners have been added to the buttons, and certainly will have ended by the time a user pushes a button, as per the rules of event-driven programming. 在将ActionListeners添加到按钮之后,方法foo()不再运行,并且根据事件驱动编程的规则,当用户按下按钮时,方法foo()当然已经结束。 Instead, though you could have the ActionListeners change the state of a class, any class, and that should suffice. 相反,尽管您可以让ActionListeners更改类的状态,但是任何类都足够了。 For instance: 例如:

class FooClass {
    private String text;

    public void foo(JButton[] buttons) {
        for (JButton i : buttons) {
            i.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    text = e.getActionCommand(); 
                }
            });
        }
    }
}

If you need greater detail on a viable solution, please tell us more details about your actual program and your specific problem. 如果您需要有关可行解决方案的更多详细信息,请告诉我们有关您的实际程序和特定问题的更多详细信息。

Now if you actually needed a method to return the value of the button pressed, you would need to do this via notification mechanisms and a call-back method, but again the details of a solution will depend on the details of the actual problem and code. 现在,如果您实际上需要一种方法来返回按下的按钮的值,则需要通过通知机制和回调方法来执行此操作,但是解决方案的细节还是取决于实际问题和代码的细节。 。


Edit 编辑

You're trying to emulate a JOptionPane. 您正在尝试模拟JOptionPane。 Your solution is to either use a JOptionPane, adding a JPanel to it, or create your own using a modal JDialog: 您的解决方案是使用JOptionPane,向其中添加JPanel或使用模式JDialog创建自己的JPanel:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class JCustomFrame2 {

   public static String showMessageFrame(Window owner, String title,
         String message, String[] textOnButtons, ImageIcon icon) {
      final JDialog dialog = new JDialog(owner);
      StringBuilder sb = new StringBuilder();

      // make it application modal!
      dialog.setModalityType(ModalityType.APPLICATION_MODAL);
      JPanel panel = new JPanel();

      panel.setLayout(new GridBagLayout());
      panel.setBackground(Color.WHITE);

      GridBagConstraints c = new GridBagConstraints();
      c.anchor = GridBagConstraints.EAST;
      c.fill = GridBagConstraints.RELATIVE;
      c.gridx = 0;
      c.gridy = 0;
      c.insets = new Insets(5, 5, 5, 5);

      JLabel messageLabel = new JLabel(message);
      messageLabel.setFont(messageLabel.getFont().deriveFont(16.0f));

      panel.add(messageLabel, c);

      c.gridy = 1;
      c.gridx = 0;
      for (int i = 0; i < textOnButtons.length; i++) {
         JButton button = new JButton(textOnButtons[i]);
         button.addActionListener(new ButtonListener(sb));
         button.setFont(button.getFont().deriveFont(16.0f));
         panel.add(button, c);
         c.gridx++;
      }

      if (icon == null) {
         dialog.setIconImage(new BufferedImage(1, 1,
               BufferedImage.TYPE_INT_ARGB_PRE));
      } else {
         dialog.setIconImage(icon.getImage());
      }
      dialog.add(panel);
      dialog.setTitle(title);
      dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
      dialog.pack();
      dialog.setVisible(true);

      return sb.toString();
   }

   private static class ButtonListener implements ActionListener {
      private StringBuilder sb;

      public ButtonListener(StringBuilder sb) {
         this.sb = sb;
      }


      @Override
      public void actionPerformed(ActionEvent e) {
         sb.append(e.getActionCommand());
         Component component = (Component) e.getSource();
         Window win = SwingUtilities.getWindowAncestor(component);
         if (win != null) {
            win.dispose();
         }
      }
   }

   public static String showMessageFrame(String title,
         String message, String[] textOnButtons, ImageIcon icon) {
      return showMessageFrame(null, title, message, textOnButtons, icon);
   }


   public static void main(String[] args) {
      String result = JCustomFrame2.showMessageFrame("Test Frame",
            "Do you really want to do this?", new String[] { "Hell No",
                  "Sure, Why Not" }, null);

      System.out.println(result);
   }
}

Why so complicated? 为什么这么复杂? whatever foo is supposed to do, it would be a lot easier to simply call another method from inside the ActionListener with the name of the button as argument. 不管foo应该做什么,用按钮名称作为参数从ActionListener内部简单地调用另一个方法会容易ActionListener Or, if you really want to achieve something like this, make the thread wait for the user to press a button. 或者,如果您确实想要实现这样的目标,则使线程等待用户按下按钮。

public void doSomething(){
    JButton[] someButtons = ...;//whereever you create the buttons

    System.out.println(foo(someButtons));
}

public static String foo(JButton[] buttons){
    final String someString = "";

    final Object lock = new Object();

    for(JButton b : buttons){
        b.addActionListener(e -> {
             someString.concat(b.getName());

             synchronized(lock){
                 lock.notifyAll();
             }
        });
    }

    synchronized(lock){
        try{
            lock.wait();
        }catch(InterruptedException e){}
    }

    return someString;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM