2011-01-20 27 views
12

JButton için ActionEvent (örneğin, düğmesine basılan/ACTION_PERFORMED) şekilde program aracılığıyla nasıl programlama yapabilirim?ActionEvent'ı JButton'a nasıl programlı olarak gönderebilirim?

bildiğim:

button.doClick(0); 

ve

button.getModel().setArmed(true); 
button.getModel().setPressed(true); 
button.getModel().setPressed(false); 
button.getModel().setArmed(false); 

Ama doğrudan o bir ActionEvent göndermek mümkün değildir?

DÜZENLEME: Bu üretim kodu değil, sadece küçük bir kişisel deney.

cevap

14

ve:

public void actionPerformed(ActionEvent ae) { 
    //SomeLogic 
} 

//... 

public void someOtherPlace() { 
    //I want to invoke SomeLogic from here though! 
} 

Ama gerçekten çözüm ActionListener o mantık ayıklamak ve ActionListener ve ikinci konumda hem onu ​​çağırmaktır Doğrudan actionPerformed yöntemi.

ActionEvent event; 
long when; 

when = System.currentTimeMillis(); 
event = new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "Anything", when, 0); 

for (ActionListener listener : button.getActionListeners()) { 
    listener.actionPerformed(event); 
} 
+4

Dikkat edilmesi gereken bir şey, ActionListeners'ın EDT'de çalıştırılmaya başlandığını varsaymasıdır, bu yüzden el ile gönderirseniz EDT'de de bunu yapmak istersiniz. –

+0

Yorumumla ilgili olarak: ActionListener ürününüzün EDT'de çalıştırılacağını varsaymanız için * belgelendirilmiş * herhangi bir yer bilen var mı? –

+4

* Burada * belgelenmiştir * http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html#event_dispatching * GUI görünür olduğunda, çoğu program düğme eylemleri gibi olaylar tarafından yürütülür ya da fare tıklaması, ** her zaman ** olay gönderen iş parçacığında işlenir * Oradan EDT'de çalıştıklarını varsayabiliriz. – OscarRyz

13

Yapabilirseniz bile, neden istersiniz? Genellikle insanlar böyle bir şey yapmak istediklerinde, düzgün bir şekilde UI'nin endişelerini iş mantığından ayırmadıkları anlamına gelir. Tipik olarak, bir ActionListener'de gerçekleşecek eyleme gerek kalmadan gerçekleşen bir mantığı çağırmak isterler. çağrı sonra bir düğmenin ActionListener s alabilirsiniz

public void someLogic() { 
    //SomeLogic 
} 

public void actionPerformed(ActionEvent ae) { 
    someLogic(); 
} 

//... 

public void someOtherPlace() { 
    someLogic(); 
} 
+0

, gerçekten soruya cevap vermez: İşte bazı çalışma koduna

. – OscarRyz

+0

@OscarRyz: OP'ye yardımcı bir "cevap" dan daha fazla yardımcı olsa bile iyi tavsiyelerde bulunmaktan çekiniyorsunuz? Bu çok yararlı değil. –

+1

Evet, ama bunun için iyi bir nedenim var. Cevabınız gerçekten bir cevap değil, bir yorumdur (gerçekten çok iyi), ve orijinal sorunun hemen altında yorumlar için bir yer var. Bu elbette kişisel değil. – OscarRyz

1

Düğmede doClick() öğesini çağırmak istemiyorsanız, düğmenin eylemiyle adlandırılan kodu çağırmanız yeterlidir. Belki de, actionPerformed yöntemini tutan her hangi bir sınıfın, diğer sınıfların çağırabileceği bir kamu yöntemini çağırmasını istediğinizde sahip olmak ve yalnızca bu yöntemi çağırmak istersiniz.

3

Eğer miras ve korunur fireActionPerformed yöntemi maruz olasıdır:

class MockButton extends JButton { 
    // bunch of constructors here 
    @Override 
    public void fireActionPerformed(ActionEvent e) { 
     super.fireActionPerformed(e); 
    } 
} 

Sonra mümkün olacak, ama tabii ki, böyle bir başvuru kullanmak zorunda:

MockButton b = .... 

b.fireActionPerformed(new Action... etc. etc 

Neden bunu yapmak istersiniz? Bilmiyorum, ancak Mark's advice

0

'u izlemenizi öneririm Pratik sorun çözüldü (bkz. Mark Peters' ve jjnguy's cevapları). Ve olası eşzamanlılık sorunlarından kaçınmak için fireActionPerformed yönteminden de bahsetmiştik (bkz. OscarRyz' answer).

Eklemek istediklerim, 'un tüm özel ve korumalı yöntemleri (fireActionPerformed dahil) arayarak, herhangi bir sınıfın alt sınıfını yansıtma gerekmeden aramalarıdır. İlk olarak, yöntem, alt sınıflarından biri değil (yöntemiyle fireActionPerformed için yani AbstractButton.class beyan inci sınıfın Class nesne olmaya method = clazz.getDeclaredMethod() (clazz ihtiyaçları olan özel veya korumalı yöntemin yansıması Method nesneyi almak değilJButton.class)). Ardından, özel veya korunan yöntemlere/alanlara erişmeye çalışırken ortaya çıkabilecek s'yi bastırmak için method.setAccessible(true) numaralı telefonu arayın. Son olarak, method.invoke()'u arayın.

Yansıma kullanmanın dezavantajlarını listeleyebilmek için yansıma hakkında yeterince bilgi sahibi değilim. Bununla birlikte, Reflection API trail'a göre mevcutturlar (bkz. "Yansımanın Gerilimleri"). Bunun iyi bir açıklama olsa da

// ButtonFireAction.java 
import javax.swing.AbstractButton; 
import javax.swing.JButton; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.lang.reflect.Method; 

public class ButtonFireAction 
{ 
    public static void main(String[] args) throws ReflectiveOperationException 
    { 
     JButton button = new JButton("action command"); 
     Class<AbstractButton> abstractClass = AbstractButton.class; 
     Method fireMethod; 

     // signature: public ActionEvent(Object source, int id, String command) 
     ActionEvent myActionEvent = new ActionEvent(button, 
                ActionEvent.ACTION_PERFORMED, 
                button.getActionCommand()); 
     button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 
      System.out.println(e.getActionCommand()); 
     } 
     }); 

     // get the Method object of protected method fireActionPerformed 
     fireMethod = abstractClass.getDeclaredMethod("fireActionPerformed", 
                ActionEvent.class); 
     // set accessible, so that no IllegalAccessException is thrown when 
     // calling invoke() 
     fireMethod.setAccessible(true); 

     // signature: invoke(Object obj, Object... args) 
     fireMethod.invoke(button,myActionEvent); 
    } 
} 
İlgili konular