问题
I'm creating a simple program where I draw a black oval where I click with my mouse. However I want a new oval to appear and the old one to disappear. How would I go about doing this? I've messed around with the removeAll() method inserted into my mousePressed method, however it isn't working for me. Is the removeAll() method even suitable for this? Or should I use something else? Sorry if the answer is obvious, but I am still new to this and trying to learn. Any advice would be immensely appreciated. Thanks.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PaintPractice extends JPanel implements MouseListener {
Random rand = new Random();
int x = rand.nextInt(450);
int y = rand.nextInt(450);
public PaintPractice(){
super();
addMouseListener(this);
}
public static void main(String[] args){
JFrame frame = new JFrame();
PaintPractice panel = new PaintPractice();
frame.setSize(500, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillOval(x, y, 50, 50);
}
@Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
removeAll();
repaint();
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
}
回答1:
Immediate solution it to Just call super.paint(g)
in the paint(Graphics g)
method.
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLACK);
g.fillOval(x, y, 50, 50);
}
The Paint Mechanism and why Should i override paintComponent()
instead of overriding paint()
:
Javadoc explains the Paint Mechanism:
By now you know that the paintComponent method is where all of your painting code should be placed. It is true that this method will be invoked when it is time to paint, but painting actually begins higher up the class heirarchy, with the paint method (defined by java.awt.Component.) This method will be executed by the painting subsystem whenever you component needs to be rendered. Its signature is:
- public void paint(Graphics g)
javax.swing.JComponent extends this class and further factors the paint method into three separate methods, which are invoked in the following order:
- protected void paintComponent(Graphics g)
- protected void paintBorder(Graphics g)
- protected void paintChildren(Graphics g)
The API does nothing to prevent your code from overriding paintBorder and paintChildren, but generally speaking, there is no reason for you to do so. For all practical purposes paintComponent will be the only method that you will ever need to override.
This is why your PaintPractice
code should invoke super.paintComponent(g)
instead.
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillOval(x, y, 50, 50);
}
Also you don't need to call removeAll()
in the mousePressed(MouseEvent e)
method.
@Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
回答2:
One possible workaround if u just want to show the newly created oval. Make your frame and panel static, then call frame.setContentPane(panel) in mousePressed.
Another working method is call g.clearRect(0, 0, getWidth(), getHeight()) in paint, but this will make the whole background whitecolor.
回答3:
Since JPanel is a subclass of JComponent, you should override
paintComponent
instead ofpaint
and also use super.paintComponent(g) in thepaintComponent
method.@Override public void paintComponent(Graphics g) { super.paintComponent(g);
When you use removeAll, all components (buttons, text fields, labels, etc) in the JPanel are removed, if any. However, you don't seem to add any components to the JPanel, so it is not necessary to call this method.
回答4:
just fillOval with the background color of the current drawing surface
{
g.setColor(...);//setColor to surface background
g.fillOval(x, y, 50, 50);
}
if you want you can clear the area: more at OracleDoc
来源:https://stackoverflow.com/questions/30005331/java-how-to-clear-graphics-from-a-jpanel