java - 在循环内添加一个 keyListener ?是否可以?

标签 java swing listener actionlistener keylistener

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

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

            }
            break;

        }  // end FILL_POLYGON

当我点击 f 时。

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

请注意,我已经有一个用于输入 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


    } 

最佳答案

我不明白为什么不。有几件事需要考虑。

关键监听器本身在事件调度线程上运行;您不希望在该线程上执行此循环,因为第二次按键的代码也在该线程中运行。因此,第一次按键需要启动 SwingWorker 或其他线程来运行填充。

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

---附录

我不会创建额外的 key 监听器,我只会使用我拥有的一个。我将在该监听器中设置一个 boolean 开关,指示我是否处于“绘图模式”;如果不是,则启动绘图循环并更改开关,如果是,则终止绘图循环并更改开关。

我会编写一个类,它的任务是执行填充循环,并使其可运行。当需要启动循环时,我将实例化它并在 SwingWorker 线程中运行它。循环会填充一点, hibernate 一点,然后再填充一点,直到完成。我对你的填充循环一无所知,所以你必须在这里填写。

您的 key 监听器可以保留对循环填充对象的引用,并调用它的方法来设置您提到的“结束循环” boolean 值。该类中的循环将检查填充之间的 boolean 值。

网络上有很多关于如何启动在事件调度线程之外运行的 SwingWorker 线程的示例;我可以创建一个,但您似乎对此没有任何具体问题,因此一般情况文档和示例应该可以使用。如果您尝试并遇到特定问题,请将问题发布回 SO。

关于java - 在循环内添加一个 keyListener ?是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15762311/

相关文章:

java - 关于类与枚举

java - Vaadin datepicker翻译月份

java - 将用户添加到聊天室 GUI 中的 JList

java - JEdi​​torPane 中 XML 标签的着色

java - 可以在 Listener 类中使用 Adapter 吗?

android - 无论如何要从 View 对象中删除 onTouchListener 吗?

java - 有没有办法让 eclipse 报告一般的 "catch (Exception e)"作为错误/警告(在 java 中)?

java - 继承和聚合 UML

java - JTable 单击行监听器

java - 在 JPanel 上添加 .GIF 时显示黑色方 block