在Swing,Java中向JPanel添加更多组件后,Repaint()不起作用

问题描述 投票:-1回答:2

我从Java开始,想要制作一个简单的乒乓游戏,以了解在java中显示内容的方法。我创建了两个类,它们都扩展了JPanel并且每16.6毫秒调用一次repaint()函数。我将两个添加到我添加到框架中的JPanel,但只添加了我添加的组件。

我已经尝试过revalidate()在两个类中的repaint()并确保Timer实际上工作,并且它的actionPerformed()方法实际上被调用。

这是主要方法:

public class Main {
  public static void main(String[] args){
    JFrame frame = new JFrame("Pong");
    //...
    JPanel mainPanel = new JPanel();

    mainPanel.add(new Player());
    mainPanel.add(new Ball(frameWidth/2, frameHeight/2 -40));

    frame.add(mainPanel);
  }
}

这是类的重要代码(对于它们来说基本相同):

public class Player extends JPanel {

  public Player(){
    setPreferredSize(new Dimension(Main.frameWidth, Main.frameHeight));
    setBackground(Color.BLACK);

    new Timer(1000/60, new ActionListener(){
      public void actionPerformed(ActionEvent e){
        update();
        repaint();
      }
    }).start();
  }
//...
  public void paintComponent(Graphics g){
    super.paintComponent(g);

    g.setColor(Color.WHITE);
    g.fillRect(x, y, width, height);
  }
}

(当然我把@Override或不必要的函数留下来缩短代码)

此代码仅绘制播放器,但我希望它显示qazxsw poi的所有组件。

这是一个你可以(希望)运行的例子。我不得不把它分成3个文件,因为我吮吸匿名课程:

main.Java

mainPanel
java swing graphics jpanel
2个回答
1
投票

import javax.swing.JFrame; import javax.swing.JPanel; public class Main { public static void main(String[] args){ JFrame frame = new JFrame("Pong"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(800, 800); JPanel mainPanel = new JPanel(); mainPanel.add(new Player()); mainPanel.add(new Ball()); frame.add(mainPanel); frame.setVisible(true); } } /////// Player.java ////// import javax.swing.JPanel; import javax.swing.Timer; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Color; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class Player extends JPanel{ private int x = 20, y = 300, width = 20, height = 100; public Player(){ setPreferredSize(new Dimension(800, 800)); setBackground(Color.BLACK); new Timer(1000/60, new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ repaint(); } }).start(); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.WHITE); g.fillRect(x, y, width, height); } } ////// Ball.java ////// import javax.swing.JPanel; import javax.swing.Timer; import java.awt.Graphics; import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class Ball extends JPanel{ private int x = 20, y = 300, width = 20, height = 100; public Ball(){ setPreferredSize(new Dimension(800, 800)); setBackground(Color.BLACK); new Timer(1000/60, new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ repaint(); } }).start(); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.WHITE); g.fillRect(x, y, width, height); } } 类的方法paintComponent()中,每次都绘制完全相同的Player。为了实现动画,每次绘制矩形时都需要更改其大小或位置或两者。你期望Rectangle做什么?它应该沿着窗口的左边缘上下移动吗?您是否看过题为Player的课程,它是Oracle Java教程的一部分?

编辑

我现在看到How to Use Swing Timers隐藏了Player,因为Ball的默认布局管理器。下面的代码基本上是您发布的代码,但我将JPanel设置为GridLayout的布局管理器。此外,java源代码文件可能包含多个类,但只有一个类必须是mainPanel。因此,在下面的代码中,只有类publicMain

public

这是GUI的屏幕截图...

import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class Main { public static void main(String[] args) { JFrame frame = new JFrame("Pong"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel mainPanel = new JPanel(new GridLayout(0, 2)); mainPanel.add(new Player()); mainPanel.add(new Ball()); frame.add(mainPanel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } } class Player extends JPanel { public Player() { setBorder(BorderFactory.createLineBorder(Color.RED, 2, false)); setPreferredSize(new Dimension(800, 800)); setBackground(Color.BLACK); new Timer(1000 / 60, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { repaint(); } }).start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.WHITE); g.fillRect(20, 100, 20, 100); } } class Ball extends JPanel { public Ball() { setBorder(BorderFactory.createLineBorder(Color.CYAN, 2, false)); setPreferredSize(new Dimension(800, 800)); setBackground(Color.BLACK); new Timer(1000 / 60, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { repaint(); } }).start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.WHITE); g.fillRect(300, 300, 10, 10); } }


0
投票

我刚刚意识到,如果我手动扩展我的窗口,第二个JPanel会出现在负责播放器的人之下!这意味着我需要以某种方式设置Panels位置,对吧?

@Abra

© www.soinside.com 2019 - 2024. All rights reserved.