簡體   English   中英

重繪/刷新JFrame

[英]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中更新汽車的位置。

OUTPUT: 在此輸入圖像描述

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM