簡體   English   中英

從按鈕/鼠標釋放中調用Java AbstractAction

[英]Calling a Java AbstractAction from a button/mouse release

在一個簡單的計算器應用程序中,我使用抽象操作來處理用鼠標單擊的按鈕以及相應的數字鍵盤按鍵(帶有鍵綁定)。 我希望在使用鍵盤時進行某些外觀上的更改,例如在按數字1鍵時更改數字1的JButton的邊框。 並在發布時將其更改回。 所有這一切。 然后,我又開始用鼠標再次按下JButton,並意識到從不調用鍵釋放操作,這顯然是因為我沒有使用鍵綁定。 所以我的問題是,有一種方法可以在鼠標釋放/按鈕抬起時調用適當的釋放抽象動作?

當我發現這個時,我最初嘗試了這個:

Abstract action(){
set border to this..
code..
code..
code..
set border to this..
}

因此,無論鍵還是鼠標,它都會改變。 但是,它沒有改變,或者運行得如此之快以至於無法檢測。

在這種情況下,注冊鼠標偵聽器沒有任何意義。 無論如何,我還是嘗試過,但似乎無法將抽象操作注冊為鼠標偵聽器。

感謝您的意見和建議。

我注冊動作偵聽器:

    btnMultiplication.addActionListener( operatorAction );
    btnDivision.addActionListener( operatorAction );
    btnAddition.addActionListener( operatorAction );
    btnSubtraction.addActionListener( operatorAction );
    btnSix.addActionListener( numberAction );
    btnSeven.addActionListener( numberAction );
    btnEight.addActionListener( numberAction );

*動作是抽象動作

我用它來輸入鍵盤

im.put( KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD0, 0, false ), "Number" );
im.put( KeyStroke.getKeyStroke( KeyEvent.VK_NUMPAD0, 0, true ), "Number Released" );
am.put( "Number", numberAction );
am.put( "Number Released", numberActionR );

我使用Number動作來更改相應jbutton的邊框。 然后,我使用數字下達來再次更改邊框。

顯然,當我用鼠標單擊時,邊框會突出顯示。 但是釋放號碼不會調用。 就像我說過的,消除所有釋放的方面,將第一個邊界更改放在抽象動作的開始,然后將最后一個邊界更改放在抽象動作的結尾,顯然進行得如此之快,以至於看不到邊界的變化。

很多人在處理鍵綁定時會錯過的一件事是,您可以注冊“ press”或“ release”事件(press是默認設置)。 因此,在您的情況下,您需要同時執行這兩項操作。 “按下”事件應“布防”並“按下”按鈕,“釋放”應“松開”並“解除”按鈕(順序很重要),例如...

我也會改變你的重點。 不必讓按鍵綁定觸發所需的動作,而是讓JButton Action這樣做,這將使您專注於讓按鍵綁定更改按鈕的狀態,最好通過使用按鈕模型來實現,該模式將允許按鈕被觸發並調用相關的Action

紐扣

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridLayout(4, 3));
            add(createButton(7, KeyEvent.VK_7, KeyEvent.VK_NUMPAD7));
            add(createButton(8, KeyEvent.VK_8, KeyEvent.VK_NUMPAD8));
            add(createButton(9, KeyEvent.VK_9, KeyEvent.VK_NUMPAD9));
            add(createButton(4, KeyEvent.VK_4, KeyEvent.VK_NUMPAD4));
            add(createButton(5, KeyEvent.VK_5, KeyEvent.VK_NUMPAD5));
            add(createButton(6, KeyEvent.VK_6, KeyEvent.VK_NUMPAD6));
            add(createButton(1, KeyEvent.VK_1, KeyEvent.VK_NUMPAD1));
            add(createButton(2, KeyEvent.VK_2, KeyEvent.VK_NUMPAD2));
            add(createButton(3, KeyEvent.VK_3, KeyEvent.VK_NUMPAD3));
            add(createButton(0, KeyEvent.VK_0, KeyEvent.VK_NUMPAD0));
        }

        protected JButton createButton(int number, int... virtualKeys) {

            NumberAction na = new NumberAction(Integer.toString(number));
            JButton btn = new JButton(na);

            InputMap im = btn.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
            ActionMap am = btn.getActionMap();

            for (int virtualKey : virtualKeys) {

                im.put(KeyStroke.getKeyStroke(virtualKey, 0, false), "number-pressed");
                im.put(KeyStroke.getKeyStroke(virtualKey, 0, true), "number-released");

            }

            am.put("number-pressed", new NumberKeyPressedAction(btn, true));
            am.put("number-released", new NumberKeyPressedAction(btn, false));

            return btn;

        }

        public class NumberAction extends AbstractAction {

            public NumberAction(String name) {
                super(name);
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(getValue(NAME) + " was clicked");
            }

        }

        public class NumberKeyPressedAction extends AbstractAction {

            private final JButton btn;
            private final boolean pressed;

            public NumberKeyPressedAction(JButton btn, boolean pressed) {
                // You could just pass the button model, but this was easier...
                this.btn = btn;
                this.pressed = pressed;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                if (pressed) {
                    btn.getModel().setArmed(pressed);
                    btn.getModel().setPressed(pressed);
                } else {
                    btn.getModel().setPressed(pressed);
                    btn.getModel().setArmed(pressed);
                }
            }

        }

    }

}

因此,我想根據MadProgrammer提供的選定解決方案發布有效的實現

我刪除了jbutton的顯式創建。 我現在這樣創建它們:

createButton( 3, 5, 1, 1, ".", "btnDecimal", KeyEvent.VK_DECIMAL );
    createButton( 1, 5, 1, 2, "0", "btnZero", KeyEvent.VK_0, KeyEvent.VK_NUMPAD0 );
    createButton( 1, 4, 1, 1, "1", "btnOne", KeyEvent.VK_1, KeyEvent.VK_NUMPAD1 );
    createButton( 2, 4, 1, 1, "2", "btnTwo", KeyEvent.VK_2, KeyEvent.VK_NUMPAD2 );
    createButton( 3, 4, 1, 1, "3", "btnThree", KeyEvent.VK_3, KeyEvent.VK_NUMPAD3 );
    createButton( 1, 3, 1, 1, "4", "btnFour", KeyEvent.VK_4, KeyEvent.VK_NUMPAD4 );
    createButton( 2, 3, 1, 1, "5", "btnFive", KeyEvent.VK_5, KeyEvent.VK_NUMPAD5 );
    createButton( 3, 3, 1, 1, "6", "btnSix", KeyEvent.VK_6, KeyEvent.VK_NUMPAD6 );
    createButton( 1, 2, 1, 1, "7", "btnSeven", KeyEvent.VK_7, KeyEvent.VK_NUMPAD7 );
    createButton( 2, 2, 1, 1, "8", "btnEight", KeyEvent.VK_8, KeyEvent.VK_NUMPAD8 );
    createButton( 3, 2, 1, 1, "9", "btnNine", KeyEvent.VK_9, KeyEvent.VK_NUMPAD9 );

createButton方法執行此操作:

private void createButton( int x, int y, int h, int w, String actionCommand, String name, int... keys ) {

    nAction na = new nAction( actionCommand );
    JButton btn = new JButton( na );
    btn.setName( name );
    InputMap im = btn.getInputMap( WHEN_IN_FOCUSED_WINDOW );
    ActionMap am = btn.getActionMap();

    for ( int virtualKey : keys ) {

        im.put( KeyStroke.getKeyStroke( virtualKey, 0, false ), "number-pressed" );
        im.put( KeyStroke.getKeyStroke( virtualKey, 0, true ), "number-released" );

    }

    am.put( "number-pressed", new NumberKeyPressedAction( btn, true ) );
    am.put( "number-released", new NumberKeyPressedAction( btn, false ) );

    GridBagConstraints gbc_btn = new GridBagConstraints();
    // gbc_btnEquals.anchor = GridBagConstraints.WEST;
    gbc_btn.fill = GridBagConstraints.BOTH;
    gbc_btn.insets = new Insets( 0, 0, 5, 5 );
    gbc_btn.gridheight = h;
    gbc_btn.gridwidth = w;
    gbc_btn.gridx = x;
    gbc_btn.gridy = y;
    frame.getContentPane().add( btn, gbc_btn );
    btn.setBackground( new Color( 225, 225, 225 ) );
    btn.setBorder( BorderFactory.createLineBorder( Color.BLACK ) );

如您所見,我按照MadProgrammer在其示例中顯示的方式創建了實例,並創建了對AbstractActions的引用。 然后,我設置各種揮桿屬性的屬性,然后設置邊框和背景。 這大大減少了代碼和變量的使用。 旁注。 createButton中的參數名稱及其用於命名按鈕的用法不再使用,將被刪除。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM