我是Java新手。我开始通过创建一个弹跳球GUI来学习。
除了一件事,我已经设法做了我想做的一切。每当它从框架边框反弹时,我都无法改变它的颜色。
我知道我不能使用getGraphics进行绘图,但在这种情况下我也不能使用绘制方法,因为我已经将它用于本程序开头的初始设置。如果我从循环中调用paint方法,它确实会改变颜色,但布局北侧的所有JButton都会神秘地消失。
使整个事情变得更加复杂的一件事就是我在Runnable Interface的void run方法中循环球的事实。
我无法弄清楚如何解决它。
你们可以在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
}
谢谢
答案 0 :(得分:3)
完成后,您的示例有几个关键问题:
错误synchronized。
过早地调用setVisible()
。
它依赖于框架的几何体,而不是封闭的面板。
相反,请使用Swing here从引用Timer
的示例开始。请注意,每个repaint()
的颜色会发生变化,每次弹跳都会播放声音。添加成员变量bounced
。
private boolean bounced;
当球反弹时,请在bounced = true
的{{1}}方法中设置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
答案 1 :(得分:1)
嗯,我得到了它的工作,但我不认为这是最好的方法!我不得不放弃Threads并选择Timer。
我到处都在阅读一个不应该混合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
}
我知道这不是专业的做法,但这是我能做的最好的事情,而且它做了我想做的事。
如果有人能在我的代码中指出一些绝对的禁忌,我会非常高兴。
感谢名单