为了账号安全,请及时绑定邮箱和手机立即绑定

如何通过按键和释放使循环开始和结束?

如何通过按键和释放使循环开始和结束?

森林海 2021-07-08 18:41:47
这是我的代码......我怎样才能让它工作,以便在用户按住按钮时运行循环并在用户释放按钮时停止?public void nextPrimeNum(){    x = false;    int b = 2;    ArrayList<Integer> next = new ArrayList<Integer>();       while(x)    {        next = factors(b);        if(next.size()==2)        {            System.out.println(b);        }        b++;    }    System.out.println("End");}public void keyPressed(KeyEvent e){    if(e.getKeyCode() == 401)    {        x = true;    }}public void keyRealesed(KeyEvent e){    if(e.getKeyCode() == 402)    {        x = false;    }}
查看完整描述

2 回答

?
慕哥6287543

TA贡献1831条经验 获得超10个赞

所以,答案是——这很复杂。它涵盖了广泛的主题,例如并发(一般)、GUI 开发、特定 API (Swing) 的最佳实践

该示例提供了两种执行“循环”的doInBackground方法(在CalculateWorker类的方法中提供)。


您可以按住JButton或按住 [kbd]Space[kbd] 栏,两者都会导致“主循环”运行,更新JTextArea结果...


import java.awt.BorderLayout;

import java.awt.EventQueue;

import java.awt.event.ActionEvent;

import java.awt.event.KeyEvent;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.atomic.AtomicBoolean;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

import javax.swing.AbstractAction;

import javax.swing.ActionMap;

import javax.swing.InputMap;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.KeyStroke;

import javax.swing.SwingWorker;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;


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 {


        private JTextArea ta;

        private CalculateWorker worker;


        public TestPane() {

            setLayout(new BorderLayout());


            ta = new JTextArea(20, 20);

            ta.setEditable(false);

            add(new JScrollPane(ta));


            worker = new CalculateWorker(ta);


            JButton btn = new JButton("Press");

            btn.getModel().addChangeListener(new ChangeListener() {

                @Override

                public void stateChanged(ChangeEvent e) {

                    System.out.println("...isRunning = " + worker.isRunning());

                    if (!worker.isRunning()) {

                        return;

                    }

                    System.out.println("...isPressed = " + btn.getModel().isPressed());

                    System.out.println("...isPaused = " + worker.isPaused());

                    if (btn.getModel().isPressed()) {

                        worker.pause(false);

                    } else {

                        worker.pause(true);

                    }

                }

            });


            add(btn, BorderLayout.SOUTH);

            worker.execute();


            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);

            ActionMap am = getActionMap();


            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "Space.released");

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "Space.pressed");


            am.put("Space.released", new CalculateAction(false, worker));

            am.put("Space.pressed", new CalculateAction(true, worker));

        }


        public class CalculateWorker extends SwingWorker<List<String>, String> {


            private AtomicBoolean run = new AtomicBoolean(true);

            private AtomicBoolean paused = new AtomicBoolean(false);


            private ReentrantLock pausedLocked = new ReentrantLock();

            private Condition pausedCondition = pausedLocked.newCondition();


            private JTextArea ta;


            public CalculateWorker(JTextArea ta) {

                this.ta = ta;

                pause(true);

            }


            public void stop() {

                run.set(false);

                pausedLocked.lock();

                pausedCondition.signalAll();

                pausedLocked.unlock();

            }


            public void pause(boolean pause) {

                paused.set(pause);

                pausedLocked.lock();

                pausedCondition.signalAll();

                pausedLocked.unlock();

            }


            public boolean isPaused() {

                return paused.get();

            }


            public boolean isRunning() {

                return run.get();

            }


            @Override

            protected List<String> doInBackground() throws Exception {

                List<String> values = new ArrayList<>(256);

                long value = 0;

                System.out.println("!! Start running");

                while (run.get()) {

                    while (paused.get()) {

                        System.out.println("!! I'm paused");

                        pausedLocked.lock();

                        try {

                            pausedCondition.await();

                        } finally {

                            pausedLocked.unlock();

                        }

                    }

                    System.out.println("!! Start loop");

                    while (!paused.get() && run.get()) {

                        value++;

                        values.add(Long.toString(value));

                        publish(Long.toString(value));

                        Thread.sleep(5);

                    }

                    System.out.println("!! Main loop over");

                }

                System.out.println("!! Run is over");

                return values;

            }


            @Override

            protected void process(List<String> chunks) {

                for (String value : chunks) {

                    ta.append(value);

                    ta.append("\n");

                }

                ta.setCaretPosition(ta.getText().length());

            }


        }


        public class CalculateAction extends AbstractAction {


            private boolean start;

            private CalculateWorker worker;


            public CalculateAction(boolean start, CalculateWorker worker) {

                putValue(NAME, "Calculate");

                this.start = start;

                this.worker = worker;

            }


            @Override

            public void actionPerformed(ActionEvent e) {

                worker.pause(start);

            }


        }


    }


}

有没有更简单的解决方案?


当然,我总是先找最难、最难理解的解决方案(讽刺)


虽然“可能”降低复杂性是可能的,但该示例提供了许多“最佳实践”概念,您可以很好地学习和理解这些概念。


该解决方案也可以根据所使用的 API 以不同方式完成,因此,它是特定 API 选择的“最简单”解决方案。


我想从控制台做到这一点!


Java 不能这样做 - 它的控制台支持充其量只是基本的,并且不支持“按键按下/释放”操作的概念(因为它在单个线程中运行,否则它不可能这样做)。


您可能会尝试“有”解决方案,但它们需要链接到本机二进制文件的第三方库才能实现,这(可能)会减少它运行的平台数量


查看完整回答
反对 回复 2021-07-14
  • 2 回答
  • 0 关注
  • 202 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号