0

JButtonaを押したときだけ戻るメソッドを作る必要があります。カスタムJButtonクラスがあります

public class MyButton extends JButton {


   public void waitForPress() {
       //returns only when user presses this button
   }

}

と実装したいですwaitForPress。基本的に、メソッドは、ユーザーがマウスでボタンを押したときにのみ戻る必要があります。JTextField私は(ユーザーがを押したときにのみ戻るために)同様の動作を達成しましたSpace

public void waitForTriggerKey() {
        final CountDownLatch latch = new CountDownLatch(1);
            KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
                public boolean dispatchKeyEvent(KeyEvent e) {
                    if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_SPACE) {
                        System.out.println("presed!");
                        latch.countDown();
                    }
                    return false;
                }
            };
            KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
            try {
                //current thread waits here until countDown() is called (see a few lines above)
                latch.await();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }  
            KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);

    }

しかし、私は同じことをしたいと思いJButtonます。

事前に:actionPerformedこれは良い考えではなく、単にイベントをJButtonから何らかのアクションを実行する必要があるとコメントしたい場合は、ここで尋ねます。私が尋ねたことだけを手伝ってください。ありがとう!!

事前に: actionPerformedを実装しても、問題が直接解決されないことにも注意してください。ボタンを押さなくてもコードが進行するからです。プログラムを停止し、ボタンが押されたときにのみ戻る必要があります。actionPerformedを使用した場合のひどい解決策は次のとおりです。

public class MyButton extends JButton implements ActionPerformed {
   private boolean keepGoing = true;

   public MyButton(String s) {
       super(s);
       addActionListener(this);
   }

   public void waitForPress() {
       while(keepGoing);
       return;
   }

   public void actionPerformed(ActionEvent e) {
       keepGoing = false;
   }

}
4

2 に答える 2

3

価値のあることとして、これがどのようにそれを行うことができるかですがwait()notify()それでもここにはもっと深い問題があると感じています。私はこれを満足のいく解決策とは見なしません:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class TestBlockingButton {

    boolean clicked = false;
    private Object toNotify;

    private void initUI() {
        JFrame frame = new JFrame(TestBlockingButton.class.getSimpleName());
        JButton button = new JButton("Click me");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                clicked = true;
                if (toNotify != null) {
                    synchronized (TestBlockingButton.this) {
                        toNotify.notify();
                    }
                }
            }
        });
        frame.add(button);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void waitForProcess() {
        toNotify = this;
        while (!clicked) {
            synchronized (this) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        System.out.println("continuing work");
    }

    public static void main(String[] args) {
        final TestBlockingButton test = new TestBlockingButton();
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                test.initUI();
            }
        });
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        pool.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("I was doing something and now I will wait for button click");
                test.waitForProcess();
                System.out.println("User has now cliked the button and I can continue my work");
            }
        });

    }
}
于 2013-01-06T22:54:31.870 に答える
2

ミューテックスを使用した実装を要求した場合、次のようになります。私は使ってActionListenerいますが、忙しい待ち時間はありません。それがあなたが望むものではない場合、あなたは少なくともBurkhardが意味するものを見ました;)

public class MyButton extends JButton implements ActionListener
{
    private Semaphore sem = new Semaphore(1);

    public MyButton(String text) throws InterruptedException
    {
        super(text);
        addActionListener(this);
        sem.acquire();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        sem.release();
    }

    public void waitForPress() throws InterruptedException {
        sem.acquire();
        //do your stuff
        sem.acquire();
        //or just
        //waitForPress()
            //if you dont want it to end.
    }

    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame();
        MyButton m = new MyButton("test");
        frame.add(m);
        frame.pack();
        frame.setVisible(true);
        m.waitForPress();
        //another time, if you only want it to block twice
        m.waitForPress();
    }
}

しかし、これはクリーンなアプローチではないと思いますが、while(isStatementTrue)-実装のようにCPU時間を消費しません。
ここで重要なことは、メインスレッドをでブロックしているということですm.waitForPress()が、あなたが書いたように、あなたはかなり経験があり、それを処理する方法を知っています。

于 2013-01-06T22:35:01.130 に答える