很好的例子的问题可能与平台有关,但我可以提供一些观察:您没有添加或删除组件,所以您不需要revalidate().
由于背景色是按钮的绑定属性,因此不需要后续调用repaint().
你,你们做需要repaint()在你的习惯里DrawingArea,但您可能需要尝试添加属性更改支持,如建议的那样。这里.
Color.white不可能brighter()和Color.black不可能darker(); Color.darkGray.darker()是Color.black().
下面的变化使用Queue以简化更改颜色。
import java.awt.BorderLayout;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 java.awt.event.ComponentAdapter;import java.awt.event.ComponentEvent;import java.util.Arrays;
import java.util.LinkedList;import java.util.Queue;import javax.swing.BorderFactory;import javax.swing.JButton;
import javax.swing.JComponent;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.SwingUtilities;
import javax.swing.Timer;/** @see https://stackoverflow.com/q/9849950/230513 */public class BallAnimation {
private int x;
private int y;
private boolean positiveX;
private boolean positiveY;
private boolean isTimerRunning;
private int speedValue;
private int diameter;
private DrawingArea drawingArea;
private Timer timer;
private Queue clut = new LinkedList(Arrays.asList(
Color.BLUE.darker(),
Color.MAGENTA.darker(),
Color.BLACK,
Color.RED.darker(),
Color.PINK,
Color.CYAN.darker(),
Color.DARK_GRAY,
Color.YELLOW.darker(),
Color.GREEN.darker()));
private Color backgroundColour;
private Color foregroundColour;
private ActionListener timerAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
x = getX();
y = getY();
drawingArea.setXYColourValues(x, y, backgroundColour, foregroundColour);
}
};
private JPanel buttonPanel;
private JButton startStopButton;
private JButton speedIncButton;
private JButton speedDecButton;
private JButton resetButton;
private JButton colourButton;
private JButton exitButton;
private ComponentAdapter componentAdapter = new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent ce) {
timer.restart();
startStopButton.setText("Stop");
isTimerRunning = true;
}
};
public BallAnimation() {
x = y = 0;
positiveX = positiveY = true;
speedValue = 1;
isTimerRunning = false;
diameter = 50;
backgroundColour = Color.white;
foregroundColour = clut.peek();
timer = new Timer(10, timerAction);
}
private void createAndDisplayGUI() {
JFrame frame = new JFrame("Ball Animation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
drawingArea = new DrawingArea(x, y, backgroundColour, foregroundColour, diameter);
drawingArea.addComponentListener(componentAdapter);
frame.add(makeButtonPanel(), BorderLayout.LINE_END);
frame.add(drawingArea, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JPanel makeButtonPanel() {
buttonPanel = new JPanel(new GridLayout(0, 1));
buttonPanel.setBorder(BorderFactory.createLineBorder(Color.darkGray, 5));
startStopButton = new JButton("Start");
startStopButton.setOpaque(true);
startStopButton.setForeground(Color.white);
startStopButton.setBackground(Color.green.darker());
startStopButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
if (!isTimerRunning) {
startStopButton.setText("Stop");
timer.start();
isTimerRunning = true;
} else if (isTimerRunning) {
startStopButton.setText("Start");
timer.stop();
isTimerRunning = false;
}
}
});
startStopButton.setBorder(BorderFactory.createLineBorder(Color.gray, 4));
buttonPanel.add(startStopButton);
colourButton = new JButton("Change Color");
colourButton.setOpaque(true);
colourButton.setForeground(Color.white);
colourButton.setBackground(clut.peek());
colourButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
//timer.restart();
clut.add(clut.remove());
foregroundColour = clut.peek();
drawingArea.setXYColourValues(x, y, backgroundColour, foregroundColour);
colourButton.setBackground(foregroundColour);
}
});
colourButton.setBorder(BorderFactory.createLineBorder(Color.gray, 4));
buttonPanel.add(colourButton);
exitButton = new JButton("Exit");
exitButton.setBackground(Color.red);
exitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
timer.stop();
System.exit(0);
}
});
exitButton.setBorder(BorderFactory.createLineBorder(Color.red.darker(), 4));
buttonPanel.add(exitButton);
return buttonPanel;
}
private int getX() {
if (x
positiveX = true;
} else if (x >= drawingArea.getWidth() - diameter) {
positiveX = false;
}
return (calculateX());
}
private int calculateX() {
if (positiveX) {
return (x += speedValue);
} else {
return (x -= speedValue);
}
}
private int getY() {
if (y
positiveY = true;
} else if (y >= drawingArea.getHeight() - diameter) {
positiveY = false;
}
return (calculateY());
}
private int calculateY() {
if (positiveY) {
return (y += speedValue);
} else {
return (y -= speedValue);
}
}
public static void main(String... args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new BallAnimation().createAndDisplayGUI();
}
};
SwingUtilities.invokeLater(runnable);
}}class DrawingArea extends JComponent {
private int x;
private int y;
private int ballDiameter;
private Color backgroundColor;
private Color foregroundColor;
public DrawingArea(int x, int y, Color bColor, Color fColor, int dia) {
this.x = x;
this.y = y;
ballDiameter = dia;
backgroundColor = bColor;
foregroundColor = fColor;
setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 5));
}
public void setXYColourValues(int x, int y, Color bColor, Color fColor) {
this.x = x;
this.y = y;
backgroundColor = bColor;
foregroundColor = fColor;
repaint();
}
@Override
public Dimension getPreferredSize() {
return (new Dimension(500, 400));
}
@Override
public void paintComponent(Graphics g) {
g.setColor(backgroundColor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(foregroundColor);
g.fillOval(x, y, ballDiameter, ballDiameter);
}}