Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';不要将.addKeyListener(this)用于静态JPanel,但需要JPanel保持静态-Java_Java_Swing_Static_Jpanel_Keylistener - Fatal编程技术网

Can';不要将.addKeyListener(this)用于静态JPanel,但需要JPanel保持静态-Java

Can';不要将.addKeyListener(this)用于静态JPanel,但需要JPanel保持静态-Java,java,swing,static,jpanel,keylistener,Java,Swing,Static,Jpanel,Keylistener,我正在尝试制作一个简单的程序,其中一个椭圆形跟随鼠标光标,如果在键盘上输入“r”、“g”或“b”,则椭圆形会相应地改变颜色 但是,我无法让我的KeyListener工作。这是我的问题。我有一个静态JPanel,因为我需要它在所有函数和方法中都可以访问。但是,Java不允许您使用静态JPanel来实现这一点。我需要JPanel是静态的,这样我就可以在按键(KeyEvent e)功能中设置颜色 我非常了解Java的基础知识,并且掌握了一些更复杂的概念。请尝试解释是否有任何复杂的代码。谢谢大家! 下面

我正在尝试制作一个简单的程序,其中一个椭圆形跟随鼠标光标,如果在键盘上输入“r”、“g”或“b”,则椭圆形会相应地改变颜色

但是,我无法让我的KeyListener工作。这是我的问题。我有一个静态JPanel,因为我需要它在所有函数和方法中都可以访问。但是,Java不允许您使用静态JPanel来实现这一点。我需要JPanel是静态的,这样我就可以在按键(KeyEvent e)功能中设置颜色

我非常了解Java的基础知识,并且掌握了一些更复杂的概念。请尝试解释是否有任何复杂的代码。谢谢大家!

下面是主类Drivers.java中的代码

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) 
    {

    }
}
下面是shapepanel.java中的代码:

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);
    }

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

这不是使字段为静态的好理由

但是,Java不允许您使用静态JPanel来实现这一点

这根本不是事实。您可以向静态和非静态字段添加KeyListener或任何其他类似的构造。您的问题与静态字段的使用限制无关。这都是因为您试图在一个静态上下文中使用
这个
,而
这个
并不存在

请注意,编译器错误可能会以以下简单方式消失:

public static ShapesPanel panel = new ShapesPanel().addKeyListener(new Drivers());
我需要JPanel是静态的,这样我就可以在按键(KeyEvent e)功能中设置颜色

这也不是字段保持静态的好理由。Swing侦听器可以通过XxxEvent参数的
getSource()
方法随时直接访问侦听的组件。例如,如果使用KeyListener,则其方法的KeyEvent参数有一个
getSource()
方法,该方法将返回正在侦听的组件(这里是图形JPanel)。如果需要引用其他组件或对象,则通过构造函数setter参数将它们传递给侦听器


  • 您的主要问题是您试图在静态上下文中使用
    this
    ,而
    this
    在此上下文中不存在
  • 第一件事是不要使面板字段为静态。您声明您非常了解Java,但随后给出了一个错误的将其设置为静态的理由。而是将其设置为实例字段,并在需要时传递实例
  • 此代码还存在许多其他问题,包括:
    • 你有一个巨大的静态main方法。这个方法应该小得多,它的工作应该是创建程序的关键对象,设置它们运行,就是这样
    • 您有一个Swing程序,它有一个
      while(true)
      和一个
      线程。代码中的sleep(…)
      在以后的迭代中(当您更好地构建了程序并在事件线程上启动了所有Swing代码时)可能会在Swing事件线程上被调用。你会想摆脱这些家伙,并考虑使用摆动定时器代替。< /LI>
    • 您的paintComponent方法不调用super的方法,从而破坏了Swing绘制链
    • 您最好不要使用键侦听器,而是使用键绑定
    • 甚至不需要
      while(true)
      块。不要轮询鼠标位置,而是使用MouseListener和/或MouseMotionListener

  • 例如:

    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());
       }
    }
    
    然后完成了。如果我需要多于1-1的关联,那么我会考虑使用EnUM或单独的类来将相关的属性保持在一起。 我有一个静态JPanel,因为我需要它在所有函数和方法中都可以访问

    这不是使字段为静态的好理由

    但是,Java不允许您使用静态JPanel来实现这一点

    这根本不是事实。您可以向静态和非静态字段添加KeyListener或任何其他类似的构造。您的问题与静态字段的使用限制无关。这都是因为您试图在一个静态上下文中使用
    这个
    ,而
    这个
    并不存在

    请注意,编译器错误可能会以以下简单方式消失:

    public static ShapesPanel panel = new ShapesPanel().addKeyListener(new Drivers());
    
    我需要JPanel是静态的,这样我就可以在按键(KeyEvent e)功能中设置颜色

    这也不是字段保持静态的好理由。Swing侦听器可以通过XxxEvent参数的
    getSource()
    方法随时直接访问侦听的组件。例如,如果使用KeyListener,则其方法的KeyEvent参数有一个
    getSource()
    方法,该方法将返回正在侦听的组件(这里是图形JPanel)。如果需要引用其他组件或对象,则通过构造函数setter参数将它们传递给侦听器


  • 您的主要问题是您试图在静态上下文中使用
    this
    ,而
    this
    在此上下文中不存在
  • 第一件事是不要使面板字段为静态。您声明您非常了解Java,但随后给出了一个错误的将其设置为静态的理由。而是将其设置为实例字段,并在需要时传递实例
  • 此代码还存在许多其他问题,包括:
    • 你有一个巨大的静态main方法。这个方法应该小得多,它的工作应该是创建程序的关键对象,设置它们运行,就是这样
    • 您有一个Swing程序,它有一个
      while(true)
      和一个
      线程。代码中的sleep(…)
      在以后的迭代中(当您更好地构建了程序并在事件线程上启动了所有Swing代码时)可能会在Swing事件线程上被调用。你会想摆脱这些家伙,并考虑使用摆动定时器代替。< /LI>