简体   繁体   English

如何将ActionListener添加到扩展JButton的类的实例中?

[英]How do I add an ActionListener to an instance of my class that extends JButton?

I instantiated a button of my class like so: 我实例化了班级的按钮,如下所示:

linkBtn = new LinkButton(
                        new URI("http://www.example.com"),
                        "Click me");

Nothing happens when I click it, so I want to add an action listener something like this: 单击它没有任何反应,因此我想添加一个动作监听器,如下所示:

linkBtn.addActionListener(SOMETHING);

I tried things like this: 我尝试过这样的事情:

linkBtn.addActionListener(new LinkButton.OpenUrlAction());

That gives the following error: 这给出了以下错误:

an enclosing instance that contains LinkButton.OpenUrlAction is required 需要包含LinkBut​​ton.OpenUrlAction的封闭实例

I haven't found the right syntax yet. 我还没有找到正确的语法。

Here's my class that extends JButton: 这是扩展JButton的类:

import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import javax.swing.JButton;

public class LinkButton extends JButton
    implements ActionListener {
    /** The target or href of this link. */
    private URI target;
    final static private String defaultText = "<HTML>Click the <FONT color=\"#000099\"><U>link</U></FONT>"
        + " to go to the website.</HTML>";

    public LinkButton(URI target, String text) {
        super(text);
        this.target = target;
        //this.setText(text);
        this.setToolTipText(target.toString());
    }
    public LinkButton(URI target) {
        this( target, target.toString() );
    }    
    public void actionPerformed(ActionEvent e) {
        open(target);
    }
    class OpenUrlAction implements ActionListener {
      @Override public void actionPerformed(ActionEvent e) {
        open(target);
      }
    }
    private static void open(URI uri) {
    if (Desktop.isDesktopSupported()) {
      try {
        Desktop.getDesktop().browse(uri);
      } catch (IOException e) { /* TODO: error handling */ }
    } else { /* TODO: error handling */ }
  }
}

I don't understand why you extends a JButton but you can add by default this listener in constructor. 我不明白为什么要扩展JButton但可以默认在构造函数中添加此侦听器。

 public LinkButton(URI target, String text) {
        super(text);
        this.target = target;
        //this.setText(text);
        this.setToolTipText(target.toString());
        this.addActionListener(this);
        //this.addActionListener(new OpenUrlAction());
    }

Or you can do this. 或者您可以这样做。

linkBtn.addActionListener(linkBtn.new OpenUrlAction()); outerObject.new InnerClass() outsideObject.new InnerClass()

Or you can modify your inner class with a constructor injection 或者您可以通过constructor injection来修改内部类

class OpenUrlAction implements ActionListener{
  private URI target;

  OpenUrlAction(URI target){
   this.target=target;
  }

  @Override
  public void actionPerformed(ActionEvent evt){
     open(this.target);
  }
}

In client code: 在客户端代码中:

`linkBtn.addActionListener(linkBtn.new OpenUrlAction(lninkBtn.getTarget)); // or the target that you want`

You could do this: 您可以这样做:

linkBtn.addActionListener(linkBtn.new OpenUrlAction());

But your program structure makes me wince. 但是您的程序结构让我畏缩了。 Myself I'd try to get Actions separate from views. 我自己将尝试使Actions与视图分离。 I also much prefer extension by composition rather than inheritance. 我也更喜欢通过组合而不是继承进行扩展。

I'm open to suggestions. 我愿意提出建议。 I don't like my program structure either... 我也不喜欢我的程序结构...

The answer's provided so far are all excellent. 到目前为止提供的答案都非常好。

Hovercraft has suggest the use of Action s, which would simply the structure of your code. Hovercraft建议使用Action ,这将只是代码的结构。

For example... 例如...

import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LinkButtonExample {

    public static void main(String[] args) {
        new LinkButtonExample();
    }

    public LinkButtonExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }

                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridBagLayout());
                    frame.add(new JButton(new OpenURLAction(new URL("http://stackoverflow.com/"))));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (MalformedURLException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class OpenURLAction extends AbstractAction {

        private URL url;

        public OpenURLAction(URL url) {

            this("<HTML>Click the <FONT color=\\\"#000099\\\"><U>link</U></FONT> to go to the website.</HTML>", url);

        }

        public OpenURLAction(String text, URL url) {

            putValue(NAME, text);
            setURL(url);

        }

        public void setURL(URL url) {
            this.url = url;
            setEnabled(
                            url != null
                            && Desktop.isDesktopSupported()
                            && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE));
            putValue(SHORT_DESCRIPTION, url == null ? null : url.toString());
        }

        public URL getURL() {
            return url;
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            if (isEnabled()) {

                URL url = getURL();
                if (url != null && Desktop.isDesktopSupported()
                                && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
                    try {
                        Desktop.getDesktop().browse(url.toURI());
                    } catch (    IOException | URISyntaxException ex) {
                        ex.printStackTrace();
                    }
                }

            }

        }
    }
}

Check out How to use Actions for more details 查看更多如何使用动作

Here what I came up with so far. 到目前为止,我想出了什么。 I added this method to my LinkButton class: 我将此方法添加到我的LinkBut​​ton类中:

public void init() {
    this.addActionListener(this);
}

Then I added this code to add the action listener: 然后,我添加了以下代码以添加动作侦听器:

linkBtnDonate.init();

It's working. 工作正常 I'm open to other suggestions. 我愿意接受其他建议。

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

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