有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java对象类未绘制到屏幕

我目前正在做一个小的编码项目,我遇到了一个问题。我回顾了我过去的工作,我似乎不明白为什么这个程序不调用绘画方法。目前我只是想在画面上画一个圆圈

下面为我试图绘制的简单圆创建窗口和对象类

public class Main {

public static void main(String[] args) {

    final int WIDTH = 700, HEIGHT = 900;

    JFrame frame = new JFrame("Physics Demo");
    JPanel content = new JPanel();

    content.setLayout(new GridLayout(1, 0, 0, 0));

    Character ball = new Character(WIDTH, HEIGHT);

    Timer changeFrame = new Timer (100, ball);

    frameSetup(frame, content, WIDTH, HEIGHT, ball, changeFrame);

}

public static void frameSetup(JFrame frame, JPanel content, int WIDTH, int HEIGHT, Character ball, Timer changeFrame){

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.setContentPane(content);

    content.add(ball);

    frame.addKeyListener(ball);

    frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));

    frame.setResizable(false);
    frame.pack();
    frame.setLocationRelativeTo(null);

    frame.setVisible(true);
    changeFrame.start();

}

}

下面的类是对象类,当我运行程序时,我从控制台得到一个响应。字符触发一次(应该触发),actionPreformed方法在带有计时器的循环上运行。出于某种原因,它不运行paint类

public class Character extends JPanel implements ActionListener, KeyListener{
/* Identify the Objects values and physics,
 * Characters weight, size and properties are below.
 * 
 */
private static final long serialVersionUID = 1L;

final int characterRadius = 30;

final double characterWeight = 0.5;

int characterY, characterX;

boolean bouncy;

public Character(int WIDTH, int HEIGHT){

    System.out.println("Character called upon... " + WIDTH);

}

public void characterObject(Graphics g, int WIDTH, int HEIGHT){

    super.paint(g);

    System.out.println("characterObject graphics called upon... " + WIDTH);

    g.setColor(Color.BLUE);
    g.fillOval(350, 450, characterRadius, characterRadius);

}

/*
 * Ball does not have any player interactions
 */

@Override
public void keyPressed(KeyEvent buttonPressed) {


}

@Override
public void keyReleased(KeyEvent arg0) {

}

@Override
public void keyTyped(KeyEvent arg0) {


}

//******************************************

@Override
public void actionPerformed(ActionEvent arg0) {

    System.out.println("actionPreformed called upon...");

    repaint();

}

}

我已经做了一段时间的尝试和错误现在,我似乎无法找出它,所以我用这个作为最后的手段

如果需要,我可以提供更多信息


共 (2) 个答案

  1. # 1 楼答案

    你为什么从characterObject打电话给super.paint?这不是定制绘画的工作方式。你不能控制绘画过程,API可以

    当API希望重新绘制组件时,需要重写调用的方法之一。例如,作为一般性建议,这将是paintComponent方法

    public class Character extends JPanel implements ActionListener, KeyListener {
    
        /* Identify the Objects values and physics,
         * Characters weight, size and properties are below.
         * 
         */
        private static final long serialVersionUID = 1L;
    
        final int characterRadius = 30;
    
        final double characterWeight = 0.5;
    
        int characterY, characterX;
    
        boolean bouncy;
    
        public Character(int WIDTH, int HEIGHT) {
    
            System.out.println("Character called upon... " + WIDTH);
    
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
            System.out.println("characterObject graphics called upon... " + WIDTH);
    
            g.setColor(Color.BLUE);
            g.fillOval(350, 450, characterRadius, characterRadius);
    
        }
    
        /*
         * Ball does not have any player interactions
         */
        @Override
        public void keyPressed(KeyEvent buttonPressed) {
    
        }
    
        @Override
        public void keyReleased(KeyEvent arg0) {
    
        }
    
        @Override
        public void keyTyped(KeyEvent arg0) {
    
        }
    
        //******************************************
        @Override
        public void actionPerformed(ActionEvent arg0) {
    
            System.out.println("actionPreformed called upon...");
    
            repaint();
    
        }
    }
    

    我建议大家阅读一下Performing Custom PaintingPainting in Swing,了解更多关于绘画如何在摇摆中实际工作的细节

    我还建议大家看看How to use Key Bindings作为KeyListener的替代品,这将解决下一个明显的问题

    您可能还想阅读Java Coding Conventions,这将使其他人更容易阅读您的代码,您也更容易阅读其他人的代码

    您正在将widthheight传递给Character构造函数,但忽略了它们,我建议您需要将这些值分配给实例字段,并在paintComponent方法中使用它们

  2. # 2 楼答案

    你不应该直接给油漆打电话。只要需要重新绘制,就会从框架中调用它。要强制重新绘制,只需调用“repaint()”

    如果从计时器调用,可能需要将调用放入EDT,这意味着EventDispatchThread:

    EventQueue.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        ball.repaint();
      }
    });
    

    哦,你真的应该覆盖绘画方法:

    @Override
    public void paint(Graphics g)
    {
      super.paint(g);
      g.setColor(Color.BLUE);
      g.fillOval(350, 450, characterRadius, characterRadius);
    }