对象类未绘制到屏幕

时间:2017-10-02 23:34:55

标签: java swing paint

我目前正在开展一个小型编码项目,但我遇到了一个问题。我查看过去的工作,我似乎无法弄清楚为什么这个程序不会调用paint方法。目前我只想在画框上画一个圆圈。

以下为我想要绘制的简单圆创建窗口和对象类。

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 个答案:

答案 0 :(得分:3)

为什么要从super.paint致电characterObject?这不是定制绘画的工作原理。你没有控制绘画过程,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,了解有关绘画在Swing中如何实际运作的详细信息。

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

您可能还希望阅读Java Coding Conventions,这样可以让其他人更轻松地阅读您的代码,让您更轻松地阅读其他人。

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

中使用它们

答案 1 :(得分:0)

你不应该直接调用paint。每当需要重绘时,都会从框架中调用它。要强制重绘,只需调用'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);
}