Я новичок в Java. Я начал учиться, создавая графический интерфейс для прыгающего шара.
Мне удалось сделать все, что я хотел сделать, кроме одного. Я не могу заставить мяч менять цвет, когда он отскакивает от границ рамки.
Я знаю, что не могу использовать getGraphics для рисования, но в этом случае я также не могу использовать метод Paint, поскольку я уже использую его для начальных настроек в начале Программы. Если я вызову метод краски из цикла, он изменит цвет, но все JButtons в Северной стороне макета таинственно исчезнут.
Единственное, что делает все это еще более сложным для меня, это тот факт, что я зацикливаю шарик в методе void run Runnable Interface.
Я не мог понять, как это решить.
Вы, ребята, можете скопировать мой код в вашу среду IDE. Единственное, что не работает, это то, что мяч остается черным и не меняет его цвет. Все остальное работает нормально.
Поэтому, пожалуйста, помогите мне понять, как я могу изменить цвет мяча всякий раз, когда он отскакивает.
благодаря
Код:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Ball extends JFrame implements Runnable, ActionListener {
private JButton start;
private JButton stop;
private JButton fast;
private JButton slow;
private JButton reset;
private int ball_x;
private int ball_y;
private int dx = 10;
private int dy = 20;
private int size = 50;
private boolean active;
private int i = 20;
private int R = 255;
private int G = 0;
private int B = 255;
private Color rgb;
private MyPanel screen;
private class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
ball_x = screen.getWidth() / 2 - 25;
ball_y = screen.getHeight() / 2 - 25;
i = 20;
g.setColor(rgb);
g.fillOval(ball_x, ball_y, size, size);
}
public void clr() {
if (R <= 10) {
R = 255;
}
R = R - 10;
if (G >= 255) {
G = 0;
}
G = G + 15;
if (B <= 20) {
B = 255;
}
B = B - 20;
}
}
public void start() {
active = true;
start.setText("Start");
start.setEnabled(false);
start.setText("Jumping...");
Thread th = new Thread(this); // Thread anlegen
th.start(); // Thread starten
}
public void stop() {
if (active) {
start.setText("Continue");
}
active = false;
start.setEnabled(true);
}
public void reset() {
active = false;
size = 50;
screen.repaint();
start.setText("Start");
start.setEnabled(true);
}
public void slow() {
i = i + 2;
if (i >= 60) {
i = 60;
}
}
public void fast() {
i = i - 2;
if (i <= 5) {
i = 5;
}
}
public void actionPerformed(ActionEvent ereignis) {
if (ereignis.getSource() == start) {
start();
}
if (ereignis.getActionCommand() == "G+") {
fast();
}
if (ereignis.getActionCommand() == "G-") {
slow();
}
if (ereignis.getActionCommand() == "Reset") {
reset();
}
if (ereignis.getActionCommand() == "Pause") {
stop();
}
}
public Ball() {
this.setTitle("Jumping Ball \u00a9 The One");
Container panel = new Container();
panel.setLayout(new BorderLayout());
JPanel subpanel = new JPanel();
//subpanel.setLayout(new GridLayout());
screen = new MyPanel();
this.setVisible(true);
this.setSize(1366, 768);
this.setContentPane(panel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
start = new JButton("Start");
fast = new JButton("G+");
slow = new JButton("G-");
reset = new JButton("Reset");
stop = new JButton("Pause");
subpanel.add(start);
subpanel.add(fast);
subpanel.add(slow);
subpanel.add(reset);
subpanel.add(stop);
panel.add(subpanel, "North");
panel.add(screen, "Center");
start.addActionListener(this);
stop.addActionListener(this);
reset.addActionListener(this);
slow.addActionListener(this);
fast.addActionListener(this);
}
public void run() {
while (active) {
screen.getGraphics().clearRect(ball_x, ball_y, size, size);
if (ball_x > (screen.getWidth() - 30) || ball_x < 25) {
dx = -dx;
size = size + 3;
screen.clr();
}
if (ball_y > (screen.getHeight() - 30) || ball_y < 25) {
dy = -dy;
size = size + 3;
screen.clr();
}
ball_x = ball_x + dx;
ball_y = ball_y + dy;
rgb = new Color(R, G, B);
screen.getGraphics().setColor(rgb);
screen.getGraphics().fillOval(ball_x, ball_y, size, size);
try {
Thread.sleep(i);
} catch (InterruptedException x) {
x.printStackTrace();
}
}
}
public static void main(String[] args) {
Ball bouncer = new Ball();
} // End of Method Main
}
Спасибо
В целом, ваш пример имеет несколько критических проблем:
Он неправильно синхронизирован.
Он вызывает setVisible()
преждевременно.
Он основан на геометрии кадра, а не на закрытой панели.
Вместо этого начните с примера, приведенного здесь, используя Timer
Swing. Обратите внимание, что цвет меняется с каждым repaint()
, и звук воспроизводится с каждым отскоком. Добавьте переменную-член, bounced
.
private boolean bounced;
Когда мяч отскакивает, установите bounced = true
в actionPerformed()
Timer
.
if (ballX - RADIUS < 0) {
…
bounced = true;
} else if (ballX + RADIUS > BOX_WIDTH) {
…
bounced = true;
}
В paintComponent()
измените цвет соответствующим образом.
g.setColor(clut.peek());
if (bounced) {
clut.add(clut.remove());
bounced = false;
}
Это может быть легче увидеть изменение с меньшим clut
.
private static final float N = 16;
Ну, я получил его на работу, но я не думаю, что это лучший способ сделать это! Мне пришлось крутить нитки и идти на Таймер.
Я читал везде, что нельзя смешивать AWT и Swing, но я не вижу никакой другой возможности, кроме panel.setLayout(new BorderLayout());
или public void paintComponent(Graphics g)
Это, очевидно, смешивание AWT и Swing Components, но я не нашел никакого чистого способа Swing для этого.
В любом случае это мой весь код:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Ball extends JFrame implements ActionListener {
private JButton start;
private JButton stop;
private JButton fast;
private JButton slow;
private JButton reset;
private int ball_x;
private int ball_y;
private int dx = 10;
private int dy = 20;
private boolean active;
private int i = 30;
private int R = 255;
private int G = 255;
private int B = 0;
private Color rgb;
private Timer trigger = new Timer(i, this);
private MyPanel screen;
private class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (start.getText() == "Start") {
ball_x = screen.getWidth() / 2 - 50;
ball_y = screen.getHeight() / 2 - 50;
}
if (start.getText() == "Jumping...") {
g.clearRect(ball_x, ball_y, 100, 100);
}
ball_x = ball_x + dx;
ball_y = ball_y + dy;
rgb = new Color(R, G, B);
g.setColor(rgb);
g.fillOval(ball_x, ball_y, 100, 100);
if (ball_x > (screen.getWidth() - 100) || ball_x < 10) {
dx = -dx;
screen.clr();
}
if (ball_y > (screen.getHeight() - 100) || ball_y < 10) {
dy = -dy;
screen.clr();
}
}
public void clr() {
if (R <= 10) {
R = 255;
}
R = R - 10;
if (G <= 20) {
G = 255;
}
G = G - 20;
if (B >= 255) {
B = 0;
}
B = B + 15;
}
}
public void start() {
active = true;
start.setText("Start");
start.setEnabled(false);
start.setText("Jumping...");
trigger.start();
screen.repaint();
}
public void stop() {
if (active) {
start.setText("Continue");
}
active = false;
start.setEnabled(true);
trigger.stop();
}
public void reset() {
active = false;
start.setText("Start");
start.setEnabled(true);
i = 100;
trigger.stop();
screen.repaint();
}
public void slow() {
i = i + 10;
if (i >= 100) {
i = 100;
}
trigger.setDelay(i);
}
public void fast() {
i = i - 10;
if (i <= 10) {
i = 10;
}
trigger.setDelay(i);
}
public void actionPerformed(ActionEvent ereignis) {
if ((ereignis.getSource() == start) || (trigger.isRunning() == true)) {
start();
}
if (ereignis.getActionCommand() == "G+") {
fast();
}
if (ereignis.getActionCommand() == "G-") {
slow();
}
if (ereignis.getActionCommand() == "Reset") {
reset();
}
if (ereignis.getActionCommand() == "Pause") {
stop();
}
}
public Ball() {
this.setTitle("Jumping Ball \u00a9 The One");
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
this.setContentPane(panel);
JPanel subpanel = new JPanel();
panel.add(subpanel, "North");
screen = new MyPanel();
screen.setBackground(Color.WHITE);
panel.add(screen, "Center");
start = new JButton("Start");
fast = new JButton("G+");
slow = new JButton("G-");
reset = new JButton("Reset");
stop = new JButton("Pause");
subpanel.add(start);
subpanel.add(fast);
subpanel.add(slow);
subpanel.add(reset);
subpanel.add(stop);
start.addActionListener(this);
stop.addActionListener(this);
reset.addActionListener(this);
slow.addActionListener(this);
fast.addActionListener(this);
this.setSize(1280, 720);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
Ball fenster = new Ball();
} // Ende der Methode Main
}
Я знаю, что это не профессиональный способ сделать это, но это лучшее, что я могу сделать, и это делает то, что я хотел.
Я буду более чем счастлив, если кто-то может указать на какой-то абсолютный отказ в моем кодексе.
Thanx