[英]Repainting/refreshing the JFrame
我有一個使用圖形g用各種物體制作的“汽車”,我想在按下按鈕時移動它。 有了這個,我沒有問題,但我的路徑有問題。 當汽車移動時,舊位置不會被清除。
汽車代碼(按下按鈕時移動):
static void gPostavi2(Graphics g){
Graphics2D g2d = (Graphics2D) g;
for(int x=500; x>89; x--){
//risanje
g2d.setColor(Color.blue);
g2d.fillRect(x+10, 351, 118, 23);
g2d.fillRect(x+12, 321, 30, 40);
g2d.fillRect(x+45, 330, 83, 20);
g2d.setColor(Color.black);
g2d.fillOval(x+19, 362, 20, 20);
g2d.fillOval(x+90, 362, 20, 20);
g2d.drawString("2t", x+70, 344);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在這個類中只有移動東西的方法,類擴展了另一個具有非移動對象,按鈕,標簽......和paintComponent方法的方法。
每當for語句出現時,我如何清除舊位置?
編輯:這里有更多的代碼。 在主類我只有這個代碼:
public static void main(String[] args) {
staticnaGrafika.dodajGumbe();
}
在staticnaGrafika中我有很多代碼,但這是paintComponent的開頭:
public class staticnaGrafika extends JPanel{
staticnaGrafika(){
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize(){
return new Dimension(1100, 740);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
//opticno stikalo
//preveri, ce ga plosca prekriva pri max. dvigu
g2d.setColor(Color.black);
g2d.fillOval(21, 148, 33, 33);
g2d.setColor(Color.yellow);
g2d.fillOval(22, 149, 31, 31);
g2d.setColor(Color.black);
g2d.fillRect(13, 159, 11, 1); //el. prikljucnice
g2d.fillRect(13, 166, 10, 1);
g2d.drawOval(7, 157, 5, 5);
g2d.drawOval(7, 164, 5, 5);
//naslon; spodnji omejevalec hoda bata
g2d.setColor(Color.black);
g2d.fillRect(5, 350, 13, 43);
g2d.fillRect(5, 380, 63, 13);
g2d.fillRect(262, 350, 408, 13);
g2d.fillRect(262, 350, 13, 43);
g2d.fillRect(212, 380, 63, 13);
這里只畫畫。 下面我有另一種方法,它添加了按鈕,actionListeners:
public static void dodajGumbe() {
final JFrame f = new JFrame();
//dvig, stop, spust
JButton dvig = new JButton("DVIGNI");
dvig.setBackground(Color.WHITE);
dvig.setFocusPainted(false);
dvig.setBounds(850,15,120,30);
JButton stop = new JButton("STOP");
stop.setBackground(Color.WHITE);
stop.setFocusPainted(false);
stop.setBounds(850,50,120,30);
JButton spust = new JButton("SPUSTI");
spust.setBackground(Color.WHITE);
spust.setFocusPainted(false);
spust.setBounds(850,85,120,30);
//komande bremen
JButton postavi2 = new JButton("nalozi breme");
postavi2.setBackground(Color.WHITE);
postavi2.setFocusPainted(false);
postavi2.setBounds(760,240,120,30);
JButton odvzemi2 = new JButton("razlozi breme");
odvzemi2.setBackground(Color.WHITE);
odvzemi2.setFocusPainted(false);
odvzemi2.setBounds(760,275,120,30);
JButton postavi5 = new JButton("nalozi breme");
postavi5.setBackground(Color.WHITE);
postavi5.setFocusPainted(false);
postavi5.setBounds(760,330,120,30);
JButton odvzemi5 = new JButton("razlozi breme");
odvzemi5.setBackground(Color.WHITE);
odvzemi5.setFocusPainted(false);
odvzemi5.setBounds(760,365,120,30);
Container gumbi = f.getContentPane();
spust.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gSpusti(f.getGraphics());
}});
dvig.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gDvigni(f.getGraphics());
}});
stop.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gStop(f.getGraphics());
}});
postavi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gPostavi2(f.getGraphics());
}});
odvzemi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gOdvzemi2(f.getGraphics());
}});
postavi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gPostavi5(f.getGraphics());
}});
odvzemi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gOdvzemi5(f.getGraphics());
}});
gumbi.add(dvig);
gumbi.add(stop);
gumbi.add(spust);
gumbi.add(postavi2);
gumbi.add(odvzemi2);
gumbi.add(postavi5);
gumbi.add(odvzemi5);
f.getContentPane();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new staticnaGrafika());
f.pack();
f.setVisible(true);
}
你可能忘了打電話
super.paintComponent(g);
在paintComponent()
方法中
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g); //Clear screen before redraw
//Your codes for painting..
}
你永遠不應該在UI線程上調用sleep()。 相反,我強烈建議您使用javax.swing.Timer和ActionListener。 就像是:
void paintCar(Graphics2D g2d, int x) {
g2d.setColor(Color.blue);
g2d.fillRect(x+10, 351, 118, 23);
g2d.fillRect(x+12, 321, 30, 40);
g2d.fillRect(x+45, 330, 83, 20);
g2d.setColor(Color.black);
g2d.fillOval(x+19, 362, 20, 20);
g2d.fillOval(x+90, 362, 20, 20);
g2d.drawString("2t", x+70, 344);
}
int x = 0;
public MyConstructor() {
new Timer(5, this).start();
}
public void actionPerformed(ActionEvent ae) {
x++;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
paintCar(g2d, x);
}
看起來問題在於您的實施。 您可以為Car對象創建一個類,並且每個car對象都會跟蹤它們自己的坐標。
對於您的情況,如果您僅在單擊按鈕時移動汽車,則甚至不需要計時器。 只需點擊每次按鈕,即可在ActionListener中更新汽車的位置。
class Car
{
private Color carColor;
private int x, y;
private int speed;
private static int carWidth = 100;
private static int carHeight = 30;
public Car(Color carColor, int speed){
this.carColor = carColor;
this.speed = speed;
x = 0;
y = 0;
}
public void moveTo(int x, int y){
this.x = x;
this.y = y;
}
public void draw(Graphics g){
//Draw a car object
g.setColor(carColor);
g.fillRect(x, y, carWidth, carHeight);
g.setColor(Color.BLACK);
//Draw Wheels
g.fillOval(x, y+carHeight, 30, 30);
g.fillOval(x+carWidth-30, y+carHeight, 30, 30);
}
public int getX(){return x;}
public int getY(){return y;}
public int getSpeed(){return speed;}
}
因此,當您移動汽車時,只需更新其位置,這就是您需要做的所有事情。 特別注意我的paintComponent()
方法。 你應該保持這種方法簡單,無雜亂。 它只負責繪畫。 汽車的所有動作都在其他地方完成。
class DrawingSpace extends JPanel implements ActionListener{
Car c1, c2, c3;
public DrawingSpace(){
setPreferredSize(new Dimension(800, 400));
c1 = new Car(Color.RED, 5);
c2 = new Car(Color.GREEN, 8);
c3 = new Car(Color.BLUE, 10);
c1.moveTo(10, 50);
c2.moveTo(10, 180);
c3.moveTo(10, 280);
}
public void moveCars(){
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
c1.draw(g);
c2.draw(g);
c3.draw(g);
}
@Override
public void actionPerformed(ActionEvent e){
//Used for timer (to animate moving cars)
c1.moveTo((c1.getX()+c1.getSpeed()), c1.getY());
c2.moveTo(c2.getX()+c2.getSpeed(), c2.getY());
c3.moveTo(c3.getX()+c3.getSpeed(), c3.getY());
if(c1.getX() > 800)
c1.moveTo(0, c1.getY());
if(c2.getX() > 800)
c2.moveTo(0, c2.getY());
if(c3.getX() > 800)
c3.moveTo(0, c3.getY());
repaint();
}
}
對於像這樣的任務,使用javax.swing.timer
而不是使用Thread.sleep()
實現自己的循環會更好更容易。
class MovingCars{
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame f = new JFrame("Moving Cars");
DrawingSpace ds = new DrawingSpace();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(ds);
f.pack();
f.setLocationRelativeTo(null);
Timer t = new Timer(50, ds); //Delay of 50 milliseconds
t.start();
}
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.