2013-06-22 3 views
0

Я инстанцирован кнопку моего класса, как так:Как добавить ActionListener в экземпляр моего класса, который расширяет JButton?

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

Ничего не происходит, когда я нажимаю, поэтому я хочу, чтобы добавить действие слушателю что-то вроде этого:

linkBtn.addActionListener(SOMETHING); 

Я пытался что-то вроде этого :

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

Это дает следующее сообщение об ошибке:

an enclosing instance that contains LinkButton.OpenUrlAction is required

Я еще не нашел правильного синтаксиса.

Вот мой класс, который расширяет 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 */ } 
    } 
} 
+0

Смотрите также [ 'LinkLabel'] (HTTP: // StackOverflow.ком/а/13871898/418556). –

+0

@AndrewThompson - Я получил свою идею от LinkLabel, но мне нужна кнопка. Я открыт для предложений, кроме моего подхода. Спасибо – MountainX

ответ

2

I'm open to suggestions. I don't like my program structure either...

Ответ предоставлен до сих пор, все они превосходны.

Hovercraft предлагает использовать Action s, что будет просто структурой вашего кода.

Например ...

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(); 
        } 
       } 

      } 

     } 
    } 
} 

How to use Actions Заканчивать для более подробной информации

0

Вот что я придумал до сих пор. Я добавил этот метод в класс LinkButton:

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

Затем я добавил этот код, чтобы добавить слушателя действий:

linkBtnDonate.init(); 

Это работает. Я открыт для других предложений.

2

Я не понимаю, почему вы расширяете 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()); 
    } 

Или вы можете это сделать.

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

Или вы можете изменить свой внутренний класс с constructor injection

class OpenUrlAction implements ActionListener{ 
    private URI target; 

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

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

В коде клиента:

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

Разве вы не сделали пример, когда 'OpenURLAction' взял параметр« URL », а затем добавил его к кнопке? Это был достойный пример – MadProgrammer

+0

@MadProgrammer i снова добавлен xD – nachokk

+0

Смотрите, это хорошая идея;) – MadProgrammer

2

Вы можете сделать это:

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

Но ваша структура программы заставляет меня вздрогнуть. Я бы попытался отделить действия от представлений. Я также предпочитаю расширение по композиции, а не наследованию.

+1

Ничего себе, узнал что-то новое +1 – MadProgrammer

+0

Я открыт для предложений. Мне тоже не нравится моя структура программы ... но я просто работаю на примерах. – MountainX