java - 如何让圆圈响应计时器?

标签 java swing jframe jpanel

我正在做一个项目,我需要一些帮助来制作我正在绘制的圆圈以响应我的计时器。我想使用我放入的 slider 让它们变得越来越慢和更快。附件是下面的代码。 (我知道我的代码将会变得一团糟,我正在使用我们教授提供的一些源代码来将 slider 显示在我的屏幕上。我只是很难让 slider /计时器与我的圈子对话。)

import java.util.ArrayList;
import java.util.Random;
import java.awt.*;
import java.awt.event.*;
import javax.swing. *;
import javax.swing.event.*;
import SpeedControlPanel.SlideListener;
public class DotsPanel extends JPanel
{
private final int SIZE = 6;  // radius of each dot
private static final long serialVersionUID = 1L;
private ArrayList<Point> pointList;
private Timer timer;
private JLabel lLabel; 
private JSlider sSlider;
private JPanel pPanel;
private Circle bouncingBall;
int sSliderHt;
private int moveX, moveY;
AnimationListener animationList;
//-----------------------------------------------------------------
//  Constructor: Sets up this panel to listen for mouse events.
//-----------------------------------------------------------------
public DotsPanel()
{
 timer = new Timer(30, new AnimationListener());
 this.setLayout(new BorderLayout());
  bouncingBall = new Circle(SIZE);
  Random rand = new Random();
  pointList = new ArrayList<Point>();
  addMouseListener (new DotsListener());
  addMouseMotionListener( new DotsListener());

  setBackground(Color.black);
  setPreferredSize(new Dimension(500, 300));

  lLabel= new JLabel("Timer Delay");
  lLabel.setAlignmentX(Component.LEFT_ALIGNMENT);

  sSlider = new JSlider(JSlider.HORIZONTAL, 0, 200, 30);
  sSlider.setMajorTickSpacing(40);
  sSlider.setMinorTickSpacing(10);
  sSlider.setPaintTicks(true);
  sSlider.setPaintLabels(true);
  sSlider.setAlignmentX(Component.LEFT_ALIGNMENT);

  sSlider.addChangeListener(new SlideListener());

  pPanel= new JPanel();
  pPanel.add(lLabel);
  pPanel.add(sSlider);

  add(pPanel, BorderLayout.SOUTH);

  animationList = new AnimationListener();
  animationList.timer.start();


  /*int[] xArray = new int[1000];
  int[] yArray = new int[1000];
  for(int i = 0; i < xArray.length; i++)
  {
  xArray[i] = rand.nextInt(10) + 1;
  yArray[i] = rand.nextInt(10) + 1;
  }*/

  }
 //-----------------------------------------------------------------
 //  Draws all of the dots stored in the list.
 //-----------------------------------------------------------------
 public void paintComponent(Graphics page)
 {
 Random rand = new Random();
 int R = rand.nextInt(256);
 int G = rand.nextInt(256);
 int B = rand.nextInt(256);

 super.paintComponent(page);

 page.setColor(new Color(R%255, (G*3)%255, (B+128)%255));

 for (Point spot : pointList)
     //page.fillOval(spot.x-SIZE, spot.y-SIZE, SIZE*2, SIZE*2);
  page.fillOval(spot.x, spot.y, SIZE*2, SIZE*2);

  page.drawString("Count: " + pointList.size(), 5, 15);

  }

   private class AnimationListener implements ActionListener {
   int xRand[];
   int yRand[];
   Random rand;

   public AnimationListener() {
       rand = new Random();

       xRand = new int[1000];
       yRand = new int[1000];

       //Filling random values between 0 to 10
       for (int i = 0; i < 1000; i++) {
           xRand[i] = rand.nextInt(10) + 1;
           yRand[i] = rand.nextInt(10) + 1;
       }
     }


    private Timer timer = new Timer(50, this);

    @Override
    public void actionPerformed(ActionEvent e) {
        //Put here for the bounce off of the wall
        Rectangle window = getBounds();

        for (int i = 0; i < pointList.size(); i++) {
            Point spot = pointList.get(i);
            spot.x += xRand[i];
            spot.y += yRand[i];

            if (spot.x <= 0) {
                xRand[i] = Math.abs(xRand[i]);
            } else if (spot.x >= window.width - (SIZE*2)) {
                xRand[i] = -Math.abs(xRand[i]);
            }

            if (spot.y <= 0) {
                yRand[i] = Math.abs(yRand[i]);
            } else if (spot.y >= window.height - (SIZE*2)) {
                yRand[i] = -Math.abs(yRand[i]);
            }
        }

        bouncingBall.move(moveX, moveY);
        // change direction if ball hits a side
        int x = bouncingBall.getX();
        int y = bouncingBall.getY();
        if (x < 0 || x >= WIDTH - SIZE)
        {
        moveX = moveX * -1;
        }
        if (y <= 0 || y >= HEIGHT - SIZE)
        {
        moveY = moveY * -1;
        }
        sSliderHt =sSlider.getSize().height;
        repaint();

        repaint();

    }

  }

  //*****************************************************************
  //  Represents the listener for mouse events.
  //*****************************************************************
  private class DotsListener implements MouseListener, MouseMotionListener
  {
  //--------------------------------------------------------------
  //  Adds the current point to the list of points and redraws
  //  the panel whenever the mouse button is pressed.
  //--------------------------------------------------------------
  public void mousePressed(MouseEvent event)
  {  
  pointList.add(event.getPoint());
     repaint();
  }

  public void mouseDragged(MouseEvent event) {
   pointList.add(event.getPoint());
  repaint();
  }

  //--------------------------------------------------------------
  //  Provide empty definitions for unused event methods.
  //--------------------------------------------------------------
  public void mouseClicked(MouseEvent event) {}
  public void mouseReleased(MouseEvent event) {}
  public void mouseEntered(MouseEvent event) {}
  public void mouseExited(MouseEvent event) {}
   }

  private class SlideListener implements ChangeListener
  {
  // ------------------------------------------------
  // Called when the state of the slider has changed;
  // resets the delay on the timer.
  // ------------------------------------------------
   public void stateChanged (ChangeEvent event)
   {
    //int sSliderHt =sSlider.getSize().height;
    timer.setDelay(sSlider.getValue());
   }
  }
  }

最佳答案

I want to make them go slower and faster using my slider that I put in.

所以在我看来,你已经有逻辑让每个圆圈在每次计时器触发时移动随机距离。

因此,只需使用 slider 更改计时器触发的时间间隔即可。然后,每次计时器触发时,您都会根据随机距离设置圆圈的新位置。

其他问题:

  1. paintComponent(...) 方法仅用于绘画。它不应该设置类的属性。例如,您不应该在方法中生成随机值。您无法控制何时调用paintComponent(),并且您不想随机更改正在绘制的对象的属性。

  2. 不要使用数组来保存随机值。首先,您不知道将添加多少对象,因此您不想设置大小限制。请改用 ArrayList。

  3. 创建一个自定义对象来包含您想要控制的所有属性。因此,您将拥有要在自定义对象中绘制的每个圆圈的大小/位置/颜色等。

参见:get width and height of JPanel outside of the class使用上述建议的示例。

关于java - 如何让圆圈响应计时器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58251755/

相关文章:

java - 将复选标记 "02713"UNIcode 符号转换为字符串

java - 我已经使用 JOptionPane.showOptionDialog 显示了 JDialog,有人可以告诉我如何将其设置为不可见或处置它吗?

java - 如何将名称添加到一个jtable的列中?

Java - 如何仅更改 JLabel 的一部分字体/添加边框

java - 重新缩放 JFrame 内容

Java:PHP 的 ord() 的实现对于 ASCII 之外的字符产生不同的结果

java - 计算总和时结果错误

java - 如何引用 GridPane 中的特定节点

java - JPanel 中的 JLabel 动画

java - 在面板中排列项目