Как заставить мяч «отскочить» от моего JSlider?(Я уже получил это, чтобы подпрыгнуть) - PullRequest
0 голосов
/ 19 февраля 2019

Я искал этот сайт и не могу найти ни одной записи, в которой бы задавался вопрос, касающийся отскока мяча от JSlider.Я изменил код, чтобы мяч отскочил от боковых сторон открытого окна, а также ускорился с помощью панели JSlider, но шар (круг) опускается за панель, которая является JSlider.Пока он прыгает вокруг окна, он проходит через JSlider, и я хочу, чтобы мяч мог рассматривать JSlider как нижнюю часть окна.Приведенный ниже код является моим конструктором.

import java.awt.*;
import java.awt.event.*;
import javax. swing. *;
import javax.swing.event.*;
public class SpeedControlPanel extends JPanel
{

  private final int WIDTH = 600;
  private final int HEIGHT = 400;
  private final int BALL_SIZE = 50;
  private Circle bouncingBall; // the object that moves
  private Timer timer;
  private int moveX, moveY; // increment to move each time
  private JPanel pSpeeder;
  private JSlider sSpeeder;
  private JLabel lSpeeder;
  Dimension height;
  // --------------------------------------------
  // Sets up the panel, including the timer
  // for the animation
  // --------------------------------------------


      public SpeedControlPanel ()
      {
        timer = new Timer(30, new ReboundListener());
        this.setLayout (new BorderLayout());
        bouncingBall = new Circle(BALL_SIZE);
        moveX = moveY = 5;
        // Set up a slider object here
        setPreferredSize (new Dimension (WIDTH, HEIGHT));
        setBackground(Color.black);
        lSpeeder = new JLabel("Timer Delay");
        lSpeeder.setAlignmentX(Component.LEFT_ALIGNMENT);

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

        sSpeeder.addChangeListener(new SlideListener());

        pSpeeder = new JPanel();
        pSpeeder.add(lSpeeder);
        pSpeeder.add(sSpeeder);

        add(pSpeeder, BorderLayout.SOUTH);
        timer.start();
      }

  // ---------------------
  // Draw the ball
  // ---------------------
      public void paintComponent (Graphics page)
      {
        super.paintComponent (page);
        bouncingBall.draw(page);
      }
  // ***************************************************
  // An action listener for the timer
  // ***************************************************
  public class ReboundListener implements ActionListener
  {
  // ----------------------------------------------------
  // actionPerformed is called by the timer -- it updates
  // the position of the bouncing ball
  // ----------------------------------------------------
      public void actionPerformed(ActionEvent action)
          {

          bouncingBall.move(moveX, moveY);
          // change direction if ball hits a side
          int x = bouncingBall.getX();
          int y = bouncingBall.getY();


          int slidePanelHt = pSpeeder.getSize().height; 

          if (x < 0 || x >= WIDTH - BALL_SIZE)
          moveX = moveX * -1;
          if (y <= 0 || y >= HEIGHT - BALL_SIZE)
          moveY = moveY * -1;
          repaint();
          }
  }
  // ***************************************************
  // A change listener for the slider.
  // ***************************************************
      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)
              {
                timer.setDelay(sSpeeder.getValue());
              }
          }
}

Есть ли способ изменить ширину / высоту JSlider, чтобы отскочить от него мяч?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Я бы порекомендовал отделить графический интерфейс от его управления путем реализации MVC Pattern .Имейте модель, которая содержит всю информацию, которая необходима представлению (графическому интерфейсу):

/*
 * The model contains the information for the view and information from the view
 * The model is independent of the user interface.
 */
class Model{

    private final int WIDTH = 600;
    private final int HEIGHT = 400;

    private int x,y, delay;
    private final int radius;

    Model(int radius) {
        this.radius = radius;
        x= radius;  y= radius; delay = 30; //default values
    }

    void move(int moveX, int moveY) {
        x += moveX; y+= moveY;
    }

    int getX() { return x;  }
    void setX(int x) { this.x = x; }

    int getY() {return y;}
    void setY(int y) { this.y = y; }

    int getRaduis() {return radius;}

    int getDelay() {return delay;}

    void setDelay(int delay) {this.delay = delay;}

    int getWidth() {return WIDTH;}

    int getHeiht() {return HEIGHT;  }
}

Имейте представление, которое использует модель для отображения графического интерфейса.Обратите внимание, что ползунок и анимация находятся на двух отдельных JPanel с, предложенных Hovercraft Full Of Eels :

/*
 * View is just that: a dumb as possible display 
 */
class View extends JPanel {

    View(Model model) {
        setLayout (new BorderLayout());
        add(new BallPane(model));                          //as explained in Hovercraft Full Of Eels
        add(new SliderPane(model), BorderLayout.PAGE_END); //answer
    }

    class BallPane extends JPanel {

        private final Model model;

        BallPane(Model model) {
            this.model = model;
            setPreferredSize (new Dimension (model.getWidth(), model.getHeiht()));
            setBackground(Color.black);
        }

        // ---------------------
        // Draw the ball
        // ---------------------
        @Override
        public void paintComponent (Graphics page)  {
            super.paintComponent (page);
            page.setColor(Color.CYAN);
            page.fillOval(model.getX(), model.getY(), model.getRaduis()*2, model.getRaduis()*2);
        }
    }

    class SliderPane extends JPanel {

        private final Model model;
        private final JSlider sSpeeder;
        SliderPane(Model model) {
            this.model = model;
            sSpeeder = new JSlider(JSlider.HORIZONTAL, 0, 200, 30);
            sSpeeder.setMajorTickSpacing(40);
            sSpeeder.setMinorTickSpacing(10);
            sSpeeder.setPaintTicks(true);
            sSpeeder.setPaintLabels(true);
            sSpeeder.setAlignmentX(Component.LEFT_ALIGNMENT);
            sSpeeder.addChangeListener(new SlideListener());
            add(sSpeeder);
        }

        // ***************************************************
        // A change listener for the slider.
        // ***************************************************
        private class SlideListener implements ChangeListener
        {
            // ------------------------------------------------
            // Called when the state of the slider has changed;
            // resets the delay on the timer.
            // ------------------------------------------------
            @Override
            public void stateChanged (ChangeEvent event)
            {
                model.setDelay(sSpeeder.getValue());
            }
        }
    }
}

Собираем все вместе: см. Следующее mvce: добавлен контроллер, управляющий моделью и видом.Для удобства и простоты следующий код можно скопировать в один файл с именем BouncingBall.java и запустить.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;   
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/*
 * The controller wires the view and model, and does the processing.
 */
public class BouncingBall {

    private final int BALL_SIZE = 25;
    private int moveX =5, moveY =5; // increment to move each time
    private final Timer timer;
    private final Model model;
    private JPanel view;

    BouncingBall() {

        model = new Model(BALL_SIZE);
        timer = new Timer(model.getDelay(), new ReboundListener());
        makeAndShowGui();
        timer.start();
    }

    private void makeAndShowGui() {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        view = new View(model);
        window.add(view);
        window.pack();
        window.setResizable(false);
        window.setVisible(true);
    }

    private void updateGui() {
        // change direction if ball hits a side
        int x = model.getX();
        int y = model.getY();

        if (x < 0 || x >= model.getWidth() - model.getRaduis()*2) {
            moveX = moveX * -1;
        }

        if (y <= 0 || y >= model.getHeiht() - model.getRaduis()*2) {
            moveY = moveY * -1;
        }

        model.setX(x+moveX);
        model.setY(y+moveY);
        timer.setDelay(model.getDelay()); //update timer
        view.repaint();
    }

    // ***************************************************
    // An action listener for the timer
    // ***************************************************
    public class ReboundListener implements ActionListener  {

        // ----------------------------------------------------
        // actionPerformed is called by the timer -- it updates
        // the position of the bouncing ball
        // ----------------------------------------------------
        @Override
        public void actionPerformed(ActionEvent action) {
            updateGui();
        }
    }

    public static void main(String[] args) {
        new BouncingBall();
    }
}

/*
 * The model contains the information for the view and information from the view
 * The model is independent of the user interface.
 */
class Model{

    private final int WIDTH = 600;
    private final int HEIGHT = 400;

    private int x,y, delay;
    private final int radius;

    Model(int radius) {
        this.radius = radius;
        x= radius;  y= radius; delay = 30; //default values
    }

    void move(int moveX, int moveY) {
        x += moveX; y+= moveY;
    }

    int getX() { return x;  }
    void setX(int x) { this.x = x; }

    int getY() {return y;}
    void setY(int y) { this.y = y; }

    int getRaduis() {return radius;}

    int getDelay() {return delay;}

    void setDelay(int delay) {this.delay = delay;}

    int getWidth() {return WIDTH;}

    int getHeiht() {return HEIGHT;  }
}

/*
 * View is just that: a dumb as possible display 
 */
class View extends JPanel {

    View(Model model) {
        setLayout (new BorderLayout());
        add(new BallPane(model));                          //as explained in Hovercraft Full Of Eels
        add(new SliderPane(model), BorderLayout.PAGE_END); //answer
    }

    class BallPane extends JPanel {

        private final Model model;

        BallPane(Model model) {
            this.model = model;
            setPreferredSize (new Dimension (model.getWidth(), model.getHeiht()));
            setBackground(Color.black);
        }

        // ---------------------
        // Draw the ball
        // ---------------------
        @Override
        public void paintComponent (Graphics page)  {
            super.paintComponent (page);
            page.setColor(Color.CYAN);
            page.fillOval(model.getX(), model.getY(), model.getRaduis()*2, model.getRaduis()*2);
        }
    }

    class SliderPane extends JPanel {

        private final Model model;
        private final JSlider sSpeeder;
        SliderPane(Model model) {
            this.model = model;
            sSpeeder = new JSlider(JSlider.HORIZONTAL, 0, 200, 30);
            sSpeeder.setMajorTickSpacing(40);
            sSpeeder.setMinorTickSpacing(10);
            sSpeeder.setPaintTicks(true);
            sSpeeder.setPaintLabels(true);
            sSpeeder.setAlignmentX(Component.LEFT_ALIGNMENT);
            sSpeeder.addChangeListener(new SlideListener());
            add(sSpeeder);
        }

        // ***************************************************
        // A change listener for the slider.
        // ***************************************************
        private class SlideListener implements ChangeListener
        {
            // ------------------------------------------------
            // Called when the state of the slider has changed;
            // resets the delay on the timer.
            // ------------------------------------------------
            @Override
            public void stateChanged (ChangeEvent event)
            {
                model.setDelay(sSpeeder.getValue());
            }
        }
    }
}

enter image description here

0 голосов
/ 19 февраля 2019
  1. Создайте оболочку JPanel, которая содержит все, и присвойте ей BorderLayout
  2. Поместите JPanel для рисования / анимации в оболочку в позиции BorderLayout.CENTER
  3. Поместите свой JSlider воболочка JPanel в позиции BorderLayout.PAGE_END
  4. Добавить оболочку в графический интерфейс вместо рисунка / анимации JPanel

Готово

...