当前位置: 首页 > 知识库问答 >
问题:

不能将。addKeyListener(this)用于静态JPanel,但需要JPanel保持静态-Java

司徒鸿文
2023-03-14
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Drivers implements KeyListener 
{

    // panel.red = panel.red - 3;
    // panel.green = panel.green - 3;
    // panel.blue = panel.blue - 3;

    public static JFrame frame = new JFrame();
    public static ShapesPanel panel = new ShapesPanel().addKeyListener(this);
    // Notice the error we get with the addKeyListener(this);

    public static void main(String[] args)
    {
        // Creates new pointer info
        PointerInfo info;
        // Creates a point (for mouse tracking)
        Point point;
        JLabel label = new JLabel();
        panel.add(label);
        // Set window size
        panel.setPreferredSize(new Dimension(300, 350));
        // Set panel inside frame
        frame.setContentPane(panel);
        // Transparent 16 x 16 pixel cursor image.
        BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
        // Create a new blank cursor.
        Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
        cursorImg, new Point(0, 0), "blank cursor");
        // Set the blank cursor to the JFrame.
        frame.getContentPane().setCursor(blankCursor);
        // Compile everything into the frame
        frame.pack();
        // Set frame to close on red exit button
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Get screen size
        Dimension sSize = Toolkit.getDefaultToolkit().getScreenSize();
        // Position frame
        frame.setLocation(sSize.width / 2 - frame.getWidth(), sSize.height / 2 - frame.getHeight());
        // Make frame visible
        frame.setVisible(true);
        // Set name of frame
        frame.setTitle("Graphical User Interface");
        // While loop to draw oval
        while(true)
        {
            // Repaint the panel 
            panel.repaint();
            // Get mouse info (for tracking)
            info = MouseInfo.getPointerInfo();
            // Set mouse location data to point
            point = info.getLocation();
            // Create variables to store coordinates of oval from mouse point location
            int x = (int) point.getX();
            int y = (int) point.getY();
            // Assign those coordinate variables to oval
            panel.x = x;
            panel.y = y;
//          System.out.println("X: " + x);
//          System.out.println("Y: " + y);
//          System.out.println("X: " + point.getX());
//          System.out.println("Y: " + point.getY());
            // Try-catch to sleep, to reduce some memory
            try
            {
                Thread.sleep(10);
            }
            catch(InterruptedException e)
            {

            }
        }
    }
    // If key is pressed
    public void keyPressed(KeyEvent e) 
    {
        // If key is R, change color and print that key has been pressed
        if (e.getKeyCode() == KeyEvent.VK_R) 
        {
            System.out.println("R");
            panel.red = 255;
            panel.green = 0;
            panel.blue = 0;
        }
        // If key is G, change color and print that key has been pressed
        if (e.getKeyCode() == KeyEvent.VK_G) 
        {
             System.out.println("G");
             panel.red = 0;
             panel.green = 255;
             panel.blue = 0;
        }
        // If key is B, change color and print that key has been pressed
        if (e.getKeyCode() == KeyEvent.VK_B) 
        {
            System.out.println("B");
            panel.red = 0;
            panel.green = 0;
            panel.blue = 255;
        }
    }
    // Doesn't do anything.. yet
    @Override
    public void keyReleased(KeyEvent e) 
    {

    }

    @Override
    public void keyTyped(KeyEvent e) 
    {

    }
}
import java.awt.*;
import javax.swing.*;

public class ShapesPanel extends JPanel 
{
    // Create x and y variables, and set as default to zero
    public int x = 0, y = 0;
    // Create RGB variables, used for changing color
    public int red = 0, green = 0, blue = 0;
    private static final long serialVersionUID = 1L;

    // Create new paintComponent function, using an override
    @Override
    public void paintComponent(Graphics g)
    {
        // Create new Graphics2D g2 version
        Graphics2D g2 = (Graphics2D) g;
        // Reset screen, so there are no trails
        g2.clearRect(0, 0, getWidth(), getHeight());
        // Set background, currently unfunctional
//      g2.setBackground(new Color(235, 150, 30));
        // Set color palette, using RGB variables
        g2.setColor(new Color(red, green, blue));
        // Use color palette to draw oval, using x and y variables
        g2.fillOval(x, y, 100, 100);
    }

}

共有1个答案

顾骏祥
2023-03-14

我有一个静态JPanel,因为我需要它在所有函数和方法中都可以访问。

这不是使字段保持静态的好理由。

但是,Java不允许您使用静态JPanel来完成这一任务。

public static ShapesPanel panel = new ShapesPanel().addKeyListener(new Drivers());
    null
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;

public class KeyBindingTest {
   // start gui
   private static void createAndShowGui() {
      KeyBindingPanel mainPanel = new KeyBindingPanel();

      JFrame frame = new JFrame("Key Binding Example");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   // start all in a thread safe manner
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class KeyBindingPanel extends JPanel {
   private static final long serialVersionUID = 1L;
   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;
   private static final Color BACKGROUND = Color.WHITE;
   private Color ovalColor = Color.blue;
   private int ovalX = PREF_W / 2;
   private int ovalY = PREF_H / 2;
   private int ovalWidth = 100;

   public KeyBindingPanel() {
      setName("Key Binding Eg");
      setBackground(BACKGROUND);

      final Map<Color, Integer> colorKeyMap = new HashMap<>();
      colorKeyMap.put(Color.BLUE, KeyEvent.VK_B);
      colorKeyMap.put(Color.RED, KeyEvent.VK_R);
      colorKeyMap.put(Color.GREEN, KeyEvent.VK_G);

      // set Key Bindings
      int condition = WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      for (final Color color : colorKeyMap.keySet()) {
         int keyCode = colorKeyMap.get(color);
         KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, 0);
         inputMap.put(keyStroke, keyStroke.toString());
         actionMap.put(keyStroke.toString(), new ColorAction(color));
      }

      MyMouse myMouse = new MyMouse();
      addMouseMotionListener(myMouse);
   }

   public void setOvalColor(Color color) {
      ovalColor = color;
      repaint();
   }

   public void setOvalPosition(Point p) {
      ovalX = p.x;
      ovalY = p.y;
      repaint();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setColor(ovalColor);
      int x = ovalX - ovalWidth / 2;
      int y = ovalY - ovalWidth / 2;
      g2.fillOval(x, y, ovalWidth, ovalWidth);
   }

   @Override // make panel bigger
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }   
}

class ColorAction extends AbstractAction {
   private static final long serialVersionUID = 1L;
   private Color color;

   public ColorAction(Color color) {
      this.color = color;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      // get reference to bound component
      KeyBindingPanel panel = (KeyBindingPanel) e.getSource();
      panel.setOvalColor(color);
   }
}

class MyMouse extends MouseAdapter {
   @Override
   public void mouseMoved(MouseEvent e) {
      // get reference to listened-to component
      KeyBindingPanel panel = (KeyBindingPanel) e.getSource();
      panel.setOvalPosition(e.getPoint());
   }
}

您可能会问,为什么在创建键绑定时使用映射

这样做使我可以使用for循环来避免代码重复。通常,更简洁的代码更容易理解和调试。这也使以后增强程序变得更加容易。例如,如果稍后我想添加color.cyan并将其与C字符相关联,我所要做的就是在映射中添加另一个条目:

colorKeyMap.put(Color.CYAN, KeyEvent.VK_C);

砰的一声就完成了。如果我需要的不仅仅是1-1关联,那么我会考虑使用枚举或单独的类来将相关属性保存在一起。

 类似资料:
  • 问题内容: 我正在尝试制作一个游戏引擎。我已经制作了Game类,但错误仍在KeyBoard类中。在这里我留下一些代码。 类别::游戏 类::键盘 类别:: KeyTest 但是错误是没有抛出异常并且输入没有被读取。谁能说我这样做的正确方法。 问题答案: 简而言之,您的面板需要专注。在创建面板的任何地方添加: 这是一个SSCCE(我建议以后再问其中一个问题): 另外,https://www.goog

  • 问题内容: 在Linux上的“ C”上, 我需要静态库来静态链接,还是需要足够的共享库?如果没有,为什么不呢?(它们不包含相同的数据吗?) 问题答案: 是的,您需要静态库来构建静态链接的可执行文件。 静态库是编译对象的捆绑包。静态链接到库时,实际上与获取该库的编译结果,将它们解压缩到当前项目中以及将它们当作自己的对象使用一样。 动态库已链接。这意味着一些信息,例如重定位,已经被修复并丢弃。 此外,

  • 问题内容: 在UNI atm上做Java课程,我遇到了骰子问题。 我有以下内容: 编译时,我得到:无法从静态上下文引用非静态变量n。我如何解决这个问题,同时让它从用户给定的值中随机化? 问题答案: 不是静态变量,因此您不能以静态方式()引用它。 由于它是类中的实例变量,并且您正在类中引用它,因此可以使用代替。

  • 你能帮我用下面的代码吗。错误是:“不能在静态上下文中使用此”

  • 问题内容: 运行Demo类将在SomeClass中调用静态方法newInstance来调用构造函数并打印问候 定义方法将包括返回类型+方法名称以及参数 newInstance的返回类型是 SomeClass 在我看来很奇怪,因为我的班级叫做SomeClass 而不是 SomeClass 为什么在SomeClass 前面需要 ?看来,如果我不包含它,将会出现一个常见错误,称为“无法对非静态类型T进行

  • 所以我尝试绑定我的Numpad键,以便在计算器应用程序中使用它们,但当我尝试从主窗口以字符串形式发送keyEvent时。java到我的MainWindowController公共void方法它给了我一个错误“不能从静态上下文引用非静态方法”,即使我的类都不是静态的?以下是主窗口代码: } 这里是MainWindowController文件(看keyPress方法)