Java 如何使关键侦听器使用图形进行绘制

Java 如何使关键侦听器使用图形进行绘制,java,swing,user-interface,graphics,keylistener,Java,Swing,User Interface,Graphics,Keylistener,除了我尝试使用键移动圆外,代码的所有内容都有效。我输入了一个System.out.printlnWorking,以查看当按下任何键时侦听器是否工作,但它根本不工作。我对鼠标侦听器也做了同样的操作,效果很好。我对编程非常陌生,我不确定我在做什么,所以任何帮助都会很好 import java.awt.*; import javax.swing.*; import java.awt.event.*; // to use listener interfaces import java.awt.geom

除了我尝试使用键移动圆外,代码的所有内容都有效。我输入了一个System.out.printlnWorking,以查看当按下任何键时侦听器是否工作,但它根本不工作。我对鼠标侦听器也做了同样的操作,效果很好。我对编程非常陌生,我不确定我在做什么,所以任何帮助都会很好

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;  // to use listener interfaces
import java.awt.geom.Ellipse2D;

public class WholePanel extends JPanel
{
   private Color foregroundColor, backgroundColor;
   private int currentDiameter, x1, y1;
   private CanvasPanel canvas;
   private JPanel buttonPanel;

   private JRadioButton filledRadio, unfilledRadio;
   private JRadioButton red, green, blue;
   private JRadioButton cyan, yellow, pink;

   private JLabel fill, foreColor, backColor;

   private ButtonGroup circleColor, canvasColor, circleFill;

   public boolean filled = false;

   public WholePanel()
   {
      backgroundColor = Color.CYAN;
      foregroundColor = Color.RED;

      currentDiameter = 100;
      x1 = 200; y1 = 100;

     //INITIATING VARIABLES
      unfilledRadio = new JRadioButton("Unfilled", true);
      filledRadio = new JRadioButton("Filled");
      red = new JRadioButton("Red", true);
      green = new JRadioButton("Green");
      blue = new JRadioButton("Blue");
      cyan = new JRadioButton("Cyan", true);
      yellow = new JRadioButton("Yellow");
      pink = new JRadioButton("Pink");

      fill = new JLabel("Circle Filling");
      foreColor = new JLabel("Foreground Color");
      backColor = new JLabel("Background Color");

     //ORGANIZING THE BUTTONS AND LABELS ON THE BUTTON PANEL
      buttonPanel = new JPanel(new GridLayout(3,4));
          buttonPanel.add(foreColor);
          buttonPanel.add(red);
          buttonPanel.add(green);
          buttonPanel.add(blue);
          buttonPanel.add(backColor);
          buttonPanel.add(cyan);
          buttonPanel.add(yellow);
          buttonPanel.add(pink);
          buttonPanel.add(fill);
          buttonPanel.add(unfilledRadio);
          buttonPanel.add(filledRadio);

     //BUTTON GROUPS ALLOW FOR ONE RADIO BUTTON SELECTION AT A TIME
      circleColor = new ButtonGroup();
          circleColor.add(red);
          circleColor.add(green);
          circleColor.add(blue);
      canvasColor = new ButtonGroup();
          canvasColor.add(cyan);
          canvasColor.add(yellow);
          canvasColor.add(pink);
      circleFill = new ButtonGroup();
          circleFill.add(unfilledRadio);
          circleFill.add(filledRadio);

     //MAKES LISTENER FOR ALL RADIO BUTTONS
      FillListener listener1 = new FillListener();
          unfilledRadio.addActionListener(listener1);
          filledRadio.addActionListener(listener1);
      ColorListener listener2 = new ColorListener();
          red.addActionListener(listener2);
          green.addActionListener(listener2);
          blue.addActionListener(listener2);
          cyan.addActionListener(listener2);
          yellow.addActionListener(listener2);
          pink.addActionListener(listener2);

      canvas = new CanvasPanel();

      JSplitPane sPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, buttonPanel, canvas);

      setLayout(new BorderLayout());
      add(sPane, BorderLayout.CENTER);
    }

   //Its description should be completed
   private class ColorListener implements ActionListener
    {
     public void actionPerformed(ActionEvent event)
      {
        //CHANGES COLOR BASED ON WHICH BUTTON IS SELECTED
         if(event.getSource() == cyan)
         {
             backgroundColor = Color.CYAN;
         }
         else if(event.getSource() == yellow)
         {
             backgroundColor = Color.YELLOW;
         }
         else if(event.getSource() == pink)
         {
             backgroundColor = Color.PINK;
         }
         if(event.getSource() == red)
         {
             foregroundColor = Color.RED;
         }
         else if(event.getSource() == green)
         {
             foregroundColor = Color.GREEN;
         }
         else if(event.getSource() == blue)
         {
             foregroundColor = Color.BLUE;
         }

        //SETS THE COLORS
         setBackground(backgroundColor);
         setForeground(foregroundColor);
      }
    } // end of ColorListener


   //Its description should be completed
   private class FillListener implements ActionListener
    {
     public void actionPerformed(ActionEvent event)
      {
        //CHECKS IF USER WANTS CIRCLE FILLED OR UNFILLED
         if(event.getSource() == unfilledRadio)
         {
             filled = false;
         }
         if(event.getSource() == filledRadio)
         {
             filled = true;
         }
      }
    }

   //CanvasPanel is the panel where a circle is drawn
   private class CanvasPanel extends JPanel
   {
    //Constructor to initialize the canvas panel
    public CanvasPanel( )
      {
        // make this canvas panel listen to keys
        addKeyListener(new DirectionListener());
        // make this canvas panel listen to mouse
        addMouseListener(new PointListener());

        setBackground(backgroundColor);
        setForeground(foregroundColor);

        //This method needs to be called for this panel to listen to keys
        //When panel listens to other things, and go back to listen
        //to keys, this method needs to be called again.
        requestFocus();
      }

     //this method draws all characters pressed by a user so far
     public void paintComponent(Graphics page)
      {
          super.paintComponent(page);
         //SETS THE COLORS BASED ON USERS CHOICE
          setBackground(backgroundColor);
          setForeground(foregroundColor);
         //DRAWS THE CIRCLE
          Graphics2D page2d = (Graphics2D)page;
         //DRAWS IT FILLED OR UNFILLED BASED ON USER CHOICE
          if(filled == true)
          {
              page.setColor(foregroundColor);
              Ellipse2D.Double circle = new  Ellipse2D.Double(x1,y1,currentDiameter,currentDiameter);
                page2d.fill(circle);
              canvas.repaint();
          }
          else if(filled == false)
          {
              page.setColor(foregroundColor);
              Ellipse2D.Double circle = new Ellipse2D.Double(x1,y1,currentDiameter,currentDiameter);
            page2d.draw(circle);
              canvas.repaint();
          }  
      }

     /** This method is overridden to enable keyboard focus */
     public boolean isFocusable()
      {
        return true;
      }

     // listener class to listen to keyboard keys
     private class DirectionListener implements KeyListener 
       {
         public void keyReleased(KeyEvent e) {}
         public void keyTyped(KeyEvent e) {}

         // in case that a key is pressed, the following will be executed.
         public void keyPressed(KeyEvent e)
          {
            //FOCUSES THE LISTENER ON THE KEYBOARD
             canvas.requestFocus();

            //CHANGES THE SIZE/POSITION OF CIRCLE IF KEYS ARE PRESSED
             if(e.getKeyChar() == KeyEvent.VK_UP)
             {
                 y1 = y1+5;
                 canvas.repaint();
             }
             else if(e.getKeyChar() == KeyEvent.VK_DOWN)
             {
                 y1 = y1-5;
                 canvas.repaint();
             }
             else if(e.getKeyChar() == KeyEvent.VK_RIGHT)
             {
                 x1 = x1+5;
                 canvas.repaint();
             }
             else if(e.getKeyChar() == KeyEvent.VK_LEFT)
             {
                 x1 = x1-5;
                 canvas.repaint();
             }
             else if(e.getKeyChar() == 's')
             {
                 if(currentDiameter >= 16)
                    currentDiameter = currentDiameter - 6;
                 canvas.repaint();
             }
             else if(e.getKeyChar() == 'b')
             {
                 currentDiameter = currentDiameter + 6;
                 canvas.repaint();
             }
           }
       } // end of DirectionListener


     // listener class that listens to the mouse
     // This class is already completed. No adjustment is needed.
     public class PointListener implements MouseListener
       {
         //in case that a user presses using a mouse,
         //it gains the focus of the keyboard keys
         public void mousePressed (MouseEvent event)
          {
            canvas.requestFocus();
          }

         public void mouseClicked (MouseEvent event) {}
         public void mouseReleased (MouseEvent event) {}
         public void mouseEntered (MouseEvent event) {}
         public void mouseExited (MouseEvent event) {}


       } // end of PointListener

    } // end of Canvas Panel Class

} // end of Whole Panel Class

KeyEvents仅调度到具有焦点的组件。默认情况下,面板不可聚焦

您需要添加:

setFocusable(true);
在类的构造函数中

您只能在可见组件上请求焦点,这意味着构造函数中的requestFocust语句将不起任何作用。此外,要使用的方法是在帧可见后再次请求FocusInWindow

最后,应该使用键绑定来侦听组件上的键事件,这样就不必担心组件有焦点。有关更多信息和示例,请参阅