在循环中添加keyListener吗?是否有可能? [英] Add a keyListener inside a loop ? Is it possible?

查看:86
本文介绍了在循环中添加keyListener吗?是否有可能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有输入此代码的侦听器:

I have listener that enters this code :

        someBoolean = true;
        case FILL_POLYGON:      
        {
            if (greenLightForFilling == true)
            {
                while (someBoolean)
                {
                    fillPressed = true;
                    fillPolygon(polyFiller);
                }

            }
            break;

        }  // end FILL_POLYGON

当我点击f时.

是否可以在该while循环内添加另一个侦听器,所以当 用户再次点击fsomeBoolean会得到false吗?

Is it possible to add another listener inside that while loop , so when the user hits f again , someBoolean would get false ?

请注意,我已经有一个用于输入开关盒的按键监听器.

Please notice , I already have a key-listener for entering the switch-case .

致谢

编辑-相关代码:

public class DrawPolygons
{
    public static void main (String[] args) throws FileNotFoundException
    {
        // attaching the menu to the frame
        final JFrame frame = new JFrame("Draw polygons");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new DrawingPanel());
        frame.pack();
        frame.setVisible(true);
    }

}


/**
 * Main class
 * @author X2
 *
 */
class DrawingPanel extends JPanel implements MouseListener, MouseMotionListener ,KeyListener
{
    /**
     *    private variables
     */

    // dimensions of the window
    private static final long serialVersionUID = 1L;
    private static final Dimension MIN_DIM = new Dimension(300, 300);
    private static final Dimension PREF_DIM = new Dimension(500, 500);


    // Hot-keys hit by the user - used for keyboard listening
    private static final char FILL_POLYGON = 'F';
    private static final char SAVE_POLYGONS = 'S';
    private static final char LOAD_POLYGONS = 'L';
    private static final char FILL_POLYGON_LOWERCASE = 'f';
    private static final char SAVE_POLYGONS_LOWERCASE = 's';
    private static final char LOAD_POLYGONS_LOWERCASE = 'l';
    private static final String SPACE = " ";


    // boolean flags
    private boolean greenLightForFilling = false;
    private boolean polygonDone = false;
    private boolean loading = false;
    private boolean loading2 = false;
    private boolean fillPressed = false;

    // data structures

    // The dummy point tracking the mouse
    private final Point trackPoint = new Point();                    

    // The list of points making up a polygon
    private ArrayList<Point> points = new ArrayList<Point>();   

    // holds edges of current polygon
    private ArrayList<Edge> edges = new ArrayList<Edge>();  

    // array-list of vertices
    private ArrayList<Point> vertices = new ArrayList<Point>();      

    // all the polygons
    private ArrayList<Polygon> polygons = new ArrayList<Polygon>();  

    // count the vertices
    private int verticesCounter = 0;

    // hold polygon vertices for the polygon-filling
    private Vector<Point> polygon = new Vector<Point>();

    private ArrayList<Point> bigVerticesList= new ArrayList<Point>();

    static int counter = 0;
    /**
     * Setting the dimensions of the window
     */
    public Dimension getMinimumSize() { return MIN_DIM; }

    public Dimension getPreferredSize() { return PREF_DIM; }

    /**
     *  The constructor
     */
    DrawingPanel()
    {
        super();
        addMouseListener(this);
        addMouseMotionListener(this);
        addKeyListener(this);
        setFocusable(true);
        requestFocusInWindow();
    }



    /**
     *  The drawing itself 
     */
    public void paintComponent(Graphics g)
    {

        super.paintComponent(g);

        // draw previous polygons

        if (this.polygons.size() > 0)
            drawPreviousPolygons(g);


        int numPoints = points.size();
        if (numPoints == 0)
            return; // nothing to draw


        Point prevPoint = points.get(0);

        // draw polygon
        Iterator<Point> it = points.iterator();
        while (it.hasNext())
        {
            Point curPoint = it.next();
            draw(g, prevPoint, curPoint);           
            prevPoint = curPoint;
        }

        // now draw tracking line or complete the polygon
        if (polygonDone == true)
        {
            Point point0 = points.get(0);       // grab the starting point (x,y) 

            // draw the last edge between the starting point & the last point 
            draw(g, prevPoint, point0);

        }

        else  // polygonDone == false
            draw(g, prevPoint, trackPoint); 

    }



    /**
     * MouseListener interface 
     */
    public void mouseClicked(MouseEvent evt)
    {
        int x = evt.getX();
        int y = evt.getY();

        if (polygonDone == false)
        {
            Point p = new Point(x,y);       // new point 
            vertices.add(p);                // add to vertices list 
            this.verticesCounter++; 
        }


        if (verticesCounter > 1)    // create a new edge 
        {
            int verSize = vertices.size();      // grab number of vertices
            Point p1 = vertices.get(verSize - 1); // grab the last vertex 
            Point p2 = vertices.get(verSize - 2); // grab the one before last vertex 

            // create the current edge between the two points P1 and P2
            Edge currentEdge = new Edge(p1,p2);

            // add the edge to the edges list 
            if (polygonDone == false)
                this.edges.add(currentEdge);

        }

        switch (evt.getClickCount())
        {
            case 1: // single-click
                if (polygonDone == true)
                {
                    /**
                     * remove all the entries from the edges list - preparing for the next polygon  
                     */


                    // first add the last edge between the final vertex and the first vertex
                    Point p1 = null ,p2 = null;
                    if (!loading)
                    {
                        p1 = this.vertices.get(0);  // grab 1st vertex 
                        int verSize = vertices.size();                      
                        p2 = vertices.get(verSize - 1);     // grab last vertex 
                        // create the last edge between the final point & the first point 
                        Edge currentEdge = new Edge(p1,p2);

                        // add the last edge to the edges list 
                        this.edges.add(currentEdge);        
                    }


                    if (loading)
                        loading = false;

                    // create the new polygon structure with the edges 
                    Polygon poly = new Polygon(this.edges , this.vertices);

                    // add the polygon to the polygons array 
                    this.polygons.add(poly);

                    // reset edges ,reset points , reset vertices-counter , reset vertices  

                    greenLightForFilling = true;

                    verticesCounter = 0;
                    edges.clear();
                    points.clear();  
                    vertices.clear();
                    polygonDone = false;
                    repaint();
                    break;

                }
                points.add(new Point(x, y));
                repaint();
                break;

            case 2: // double-click
                polygonDone = true;
                points.add(new Point(x, y));
                repaint();
                break;

            default: // ignore anything else
                break;
        }
    }






    /**
     * MouseMotionListener interface 
     */
    public void mouseMoved(MouseEvent evt)
    {
        trackPoint.x = evt.getX();
        trackPoint.y = evt.getY();
        repaint();
    }



    /**
     * draw points and lines 
     * @param g
     * @param p1
     * @param p2
     */
    private void draw(Graphics g, Point p1, Point p2)
    {
        int x1 = p1.x;
        int y1 = p1.y;

        int x2 = p2.x;
        int y2 = p2.y;

        // draw the line
        g.setColor(Color.green.darker());
        g.drawLine(x1 + 3, y1 + 3, x2 + 3, y2 + 3);

        // now just paint the edge between those two points
        g.setColor(Color.green);
        g.fillOval(x1, y1, 8, 8);

        g.setColor(Color.black);
        g.fillOval(x2, y2, 8, 8);

        greenLightForFilling = false;       
    }





    /**
     * Run on the arrayList of the Polygons , and draw the previous polygons 
     * that we already made 
     * @param g
     */
    private void drawPreviousPolygons(Graphics g) 
    {
        int i = 0;

        while (i < this.polygons.size())
        {
            Polygon currentPoly = polygons.get(i);  // grab current polygon
            int j = 0; 

            ArrayList<Edge> edges = currentPoly.getPolygonEdges();


            // draw the edges of the polygon
            while (j < edges.size()) // run on all the edges of the polygon
            {
                Edge edgeCurrent = edges.get(j);        // grab current edge

                // drawing the edge 

                // now draw it - grab the two points that create the edge
                int x1 = edgeCurrent.getX1();
                int y1 = edgeCurrent.getY1();

                int x2 = edgeCurrent.getX2();
                int y2 = edgeCurrent.getY2();

                // draw the line first so that the points appear on top of the line ends, not below
                g.setColor(Color.green.darker());
                g.drawLine(x1 + 3, y1 + 3, x2 + 3, y2 + 3);

                // now just paint the edge between those two points
                g.setColor(Color.green);
                g.fillOval(x1, y1, 8, 8);

                g.setColor(Color.black);
                g.fillOval(x2, y2, 8, 8);

                // proceed to next edge 

                j++; 


            }

            i++;    // next polygon

        }


    }


    @Override
    public void keyTyped(KeyEvent keyEvent) 
    {
        PolygonFiller polyFiller = new PolygonFiller();
        char key = keyEvent.getKeyChar();


        switch(key)
        {
            /**
             *  Fill the polygons 
             */
            case FILL_POLYGON:      
            {
                if (greenLightForFilling == true)
                {
                    while (true)
                    {
                        fillPolygon(polyFiller);
                    }

                }
                break;

            }  // end FILL_POLYGON


            case FILL_POLYGON_LOWERCASE:
            {
                if (greenLightForFilling == true)
                {
                    fillPolygon(polyFiller);
                }
                break;              

            }

            /**
             *  save all polygons in a .scn file
             */
            case SAVE_POLYGONS :         
            {
                if (greenLightForFilling == true)
                {
                    saveWorkspace();
                } 
                break;  
            }   // end SAVE_POLYGONS



            case SAVE_POLYGONS_LOWERCASE:
            {
                if (greenLightForFilling == true)
                {
                    saveWorkspace();
                } 
                break;  
            }

            /**
             *  Delete everything & load all polygons from .scn file
             */
            case LOAD_POLYGONS:      
            {
                loadWorkspace();
                break;
            }   

            case LOAD_POLYGONS_LOWERCASE:
            {
                loadWorkspace();
                break;
            }

            default: break;  
        } // end switch


    } 

推荐答案

我不明白为什么不这样做.有两件事要考虑.

I don't see why not. There are a couple of things to consider.

键侦听器本身在事件分发线程上运行;您不希望在该线程上发生此循环,因为第二个按键的代码也在该线程中运行.因此,第一次按键需要启动SwingWorker或其他线程来运行填充.

The key listener itself runs on the event dispatch thread; you don't want this loop on that thread, because the code for the second keypress also runs in that thread. So the first keypress needs to start a SwingWorker or some other thread to run the fill.

我建议多边形填充器运行缓慢(进行一点填充,然后以某种方式暂停,除非填充需要花费相当长的时间),否则它必然会在第二次按键之前完成填充.可能还需要刷新"填充输出,以便缓冲不会消除可见的效果.

I would suggest that the polygon filler either operate slowly (do a little filling and then pause somehow unless filling takes a noticeable amount of time), otherwise it is bound to complete filling before the second keypress. It may also need to 'flush' the filling output so that buffering doesn't remove the visible effect.

---附录

我不会创建其他按键监听器,只会使用我拥有的按键监听器.我将在该侦听器中使用一个布尔型开关,该开关指示我是否处于绘图模式".如果不是,则启动绘图循环并更改开关;如果是,则终止绘图循环并更改开关.

I wouldn't create an additional keylistener, I would just use the one I had. I would have a boolean switch in that listener that indicated whether I was in "drawing mode" or not; if not, start the drawing loop and change the switch, if so, terminate the drawing loop and change the switch.

我将编写一个类来执行填充循环并使其可运行.是时候开始循环了,我将其实例化并在SwingWorker线程中运行它.循环将充满一点,睡一会儿,然后再填充多一点,直到完成.我对您的填充循环一无所知,因此您必须在此处填写.

I would write a class which job it was to execute the filling loop, and make it runnable. When it was time to start the loop, I would instantiate it and run it in a SwingWorker thread. The loop would fill a little, sleep a little, and then fill a little more until done. I don't know anything about your fill loop, so you'll have to fill in here.

您的keylistener可以保留对循环填充对象的引用,并在其上调用一个方法来设置您提到的结束循环"布尔值.该类中的循环将检查两次填充之间的布尔值.

Your keylistener could keep a reference to the loop-filling object, and call a method on it to set the "end loop" boolean you mention. The loop in that class would check the boolean between fills.

网络上有许多示例,介绍了如何启动在事件分发线程之外运行的SwingWorker线程.我可以创建一个,但是您似乎对此没有任何特定的问题,因此应该使用一般情况的文档和示例.如果您尝试过并遇到一个特定的问题,则将该问题发回至SO.

There are many examples available on the web of how to start a SwingWorker thread that operates outside the event dispatch thread; I could create one, but you don't seem to have any specific question about it, so the general-case documentation and examples should serve. If you try it and run into a specific problem, post that question back to SO.

这篇关于在循环中添加keyListener吗?是否有可能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆