2011-02-24 24 views
47

Bir Swing JButton'unu, ilgili tüm eylem/fare olaylarını kaydedecek ve kullanıcı tarafından görülebilecek şekilde programlı olarak nasıl tıklardım (örneğin; onlar gerçekten tıkladılar)?Java Swing'de bir GUI düğmesini program aracılığıyla tıklatma

Düğme, çalıştığım aynı uygulamada; Başka bir uygulamada bir düğmeyi kontrol etmeye çalışmıyorum. Olayları doğrudan kuyruğa enjekte edebildiğimi varsayalım, ancak mümkünse bu yaklaşımdan kaçınmayı tercih ediyorum ve bunu yaparken görünür bir tıklama göstermezdim.

java.awt.Robot sınıfının fareyi hareket ettirmek ve fareyi tıklatmak için belirli bir düğmeyi tıklatmamak için yöntemler sunduğunu görüyorum.

+0

olası yinelenen (http: // stackoverflow. com/questions/4753004/how-do-i-programatik-send-actionevent-to-jbutton) – OscarRyz

cevap

87

Eğer doClick() kullanarak denediniz ne olursa olsun dinleyici çağrı istiyorum?

+1

DoClick() işi yapacak gibi görünüyor! Bunu daha önce fark etmeliydim. Sanırım özledim çünkü doğrudan JButton'da değil, AbstractButton'dan miras alınmış. – Gigatron

+4

@Gigatron - Evet. Soyutlama bazen sizin için neyin mevcut olduğunu bilmeyi zorlaştırabilir (özellikle iyi bir dokümantasyon yoksa - JavaDocs'a şükürler olsun). Yardımcı olduğuma sevindim! – JasCav

+7

Belki 'click()' veya '(() tuşuna basarsanız daha iyi isimler olurdu –

9

doClick() varsa, düğmeye gerçekten fareyi hareket ettirin ve onu basabilirsiniz:

public void click(AbstractButton button, int millis) throws AWTException 
{ 
    Point p = button.getLocationOnScreen(); 
    Robot r = new Robot(); 
    r.mouseMove(p.x + button.getWidth()/2, p.y + button.getHeight()/2); 
    r.mousePress(InputEvent.BUTTON1_MASK); 
    try { Thread.sleep(millis); } catch (Exception e) {} 
    r.mouseRelease(InputEvent.BUTTON1_MASK); 
} 
+0

Bu benim daha önce düşündüğüm yaklaşımdı, ama daha basit bir çözüm olması gerektiğini hissettim .. ve gerçekten de doClick() 'un basit bir çözümü var. – Gigatron

+0

Bu şekilde emin misiniz, keylogger'lar veya daha iyisi: moueloggers bu olayı da yakalamış olacak: D –

+1

Robot sınıfının duraklama işlemini yapan bir gecikme() yöntemi zaten var. –

2

asker button.doClick() memnun olmasına rağmen Mnemonik ayarlandıktan sonra, button.setMnemonic(KeyEvent.VK_A) ile olan gibi bir şey arıyordum. ALT + A'yı herhangi bir şey olmaksızın (görsel değişiklik hariç) basılı tutabilirsiniz. Ve anahtar A'nın (ALT ile veya olmadan) serbest bırakılması üzerine, düğme bir ActionEvent çıkarır.

ben, button.getModel() ile ( Java 8 API bakınız) buttonModel olsun sonra görsel (hem mnemonic'ler ile değiştirilir) model.setPressed(true); model.setArmed(true); ile düğmesine basın ve görsel false hem ayarlayarak düğmesini bırakın tespit ettik. Düğme hem basılı hem de basılıyken model.setPressed(false) çağrıldığında, düğme otomatik olarak bir ActionEvent yangın yapar (çağırarak model.setArmed(false) düğmeyi görsel olarak değiştirir).

Bir düğme tetiklenir ve bir ActionEvent modeli silahlı iken fare serbest bırakıldığında, ateşlenir [...] [buttonModel Java API belgelerine alıntı]

yapmak için Uygulama, tuş görünürken tuş basmalarına tepki verir (içeren pencere veya odak sahibi olması gereken düğme olmadan, yani penceredeki başka bir bileşen odaklandığında) Tuş bağlarını kullandım (bkz. Official Java Tutorial).

Çalışma kodu: Düğmeye görsel olarak basmak için ÜSTKRKT + A tuşlarına basın (mnemonik button.setMnemonic() ile ayarlandıktan sonra tuşa basarak ALT tuşuna basmak). Ve konsoldaki eylem komutunu ("düğme") yazdırmak için tuşu bırakın.

// MnemonicCode.java 
import javax.swing.*; 
import java.awt.event.*; 

public class MnemonicCode extends JFrame 
{ 
    public MnemonicCode(int keyCode) 
    { 
    JButton button = new JButton("button"); 

    getContentPane().add(button); 
    addMnemonicToButton(button,keyCode); 
    button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 
     System.out.println(e.getActionCommand()); 
     } 
    }); 

    pack(); 
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    setVisible(true); 
    } 

    public static void main(String[] args) throws Exception 
    { 
    MnemonicCode bp = new MnemonicCode(KeyEvent.VK_A); 
    } 

    void addMnemonicToButton(JButton button,int keyCode) 
    { 
    int shiftMask = InputEvent.SHIFT_DOWN_MASK; 

    // signature: getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) 
    KeyStroke keyPress = KeyStroke.getKeyStroke(keyCode,shiftMask,false); 
    KeyStroke keyReleaseWithShift = KeyStroke.getKeyStroke(keyCode,shiftMask,true); 

    // get maps for key bindings 
    InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
    ActionMap actionMap = button.getActionMap(); 

    // add key bindings for pressing and releasing the button 
    inputMap.put(keyPress,"press"+keyCode); 
    actionMap.put("press"+keyCode, new ButtonPress(button)); 

    inputMap.put(keyReleaseWithShift,"releaseWithShift"+keyCode); 
    actionMap.put("releaseWithShift"+keyCode, new ButtonRelease(button)); 

    ///* 
    // add key binding for releasing SHIFT before A 
    // if you use more than one modifier it gets really messy 
    KeyStroke keyReleaseAfterShift = KeyStroke.getKeyStroke(keyCode,0,true); 
    inputMap.put(keyReleaseAfterShift,"releaseAfterShift"+keyCode); 
    actionMap.put("releaseAfterShift"+keyCode, new ButtonRelease(button)); 
    //*/ 
    } 

    class ButtonPress extends AbstractAction 
    { 
    private JButton button; 
    private ButtonModel model; 
    ButtonPress(JButton button) 
    { 
     this.button = button; 
     this.model = button.getModel(); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     // visually press the button 
     model.setPressed(true); 
     model.setArmed(true); 

     button.requestFocusInWindow(); 
    } 
    } 

    class ButtonRelease extends AbstractAction 
    { 
    private ButtonModel model; 
    ButtonRelease(JButton button) 
    { 
     this.model = button.getModel(); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     if (model.isPressed()) { 
     // visually release the button 
     // setPressed(false) also makes the button fire an ActionEvent 
     model.setPressed(false); 
     model.setArmed(false); 
     } 
    } 
    } 
} 
0

Courteaux cevabı @ dayanarak, bu yöntem, bir JTable ilk hücreyi tıklamaları: [? Programlama JButton için ActionEvent göndermek nasıl] arasında

private void clickFirstCell() { 
    try { 
     jTable1.changeSelection(0, 0, false, false); 
     Point p = jTable1.getLocationOnScreen(); 
     Rectangle cellRect = jTable1.getCellRect(0, 0, true); 
     Robot r = new Robot(); 
     Point mouse = MouseInfo.getPointerInfo().getLocation(); 
     r.mouseMove(p.x + cellRect.x + cellRect.width/2, 
       p.y + cellRect.y + cellRect.height/2); 
     r.mousePress(InputEvent.BUTTON1_MASK); 
     try { 
      Thread.sleep(50); 
     } catch (Exception e) { 
     } 
     r.mouseRelease(InputEvent.BUTTON1_MASK); 
     r.mouseMove(mouse.x, mouse.y); 
    } catch (AWTException ex) { 
    } 
} 
İlgili konular