首页 > 解决方案 > 重新绘制jframe的更好方法

问题描述

我正在为大学构建一个项目,我的框架中有几个形状,我需要对这些对象进行一些操作。例如:

Figure fig = figs.get(figs.size() -1);
fig.mov(dx,dy);
figs.set(figs.size() -1, fig);
repaint();

我有一个数字数组,每次我拖动/移动 1 个数字时,我都必须更新该数组并且也这样做repaint(),这将在按下键盘箭头之一时发生。

我的问题是,尽管 repaint() 函数很快,但当我对 1 个对象进行多次移动时,屏幕会变白几次,很难看清。我不太了解java,也不知道如何解决这个问题。我想知道是否有人有任何想法可以帮助我。

例子:

数字测试/Figure.java

package figurestest;
import java.awt.Graphics;

public abstract class Figure {
    public int x, y;
    public int w, h;

    public Figure (int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }

    public abstract void paint (Graphics g);
    public abstract void mov (int dx, int dy);
}

数字测试/rect.java

package figurestest;

import java.awt.*;

public class Rect extends Figure {

    public Rect (int x, int y, int w, int h) {
        super(x, y, w, h);
    }

    public void paint (Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.fillRect(this.x, this.y, this.w, this.h);
        g2d.drawRect(this.x,this.y, this.w,this.h);
    }

    public void mov (int dx, int dy){

    this.x += dx;
    this.y += dy;
    }
}

testapp.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Random;


import figurestest.*;

class TestApp {
    public static void main (String[] args) {
        ListFrame frame = new ListFrame();
        frame.setVisible(true);

    }
}

class ListFrame extends JFrame {
    ArrayList<Figure> figs = new ArrayList<Figure>();
    Random rand = new Random();

    ListFrame () {
        this.addWindowListener (
            new WindowAdapter() {
                public void windowClosing (WindowEvent e) {
                    System.exit(0);
                }
            }
        );

        this.addKeyListener (
            new KeyAdapter() {
                public void keyPressed (KeyEvent evt) {
                Dimension size = getContentPane().getSize();
                
                int x = rand.nextInt(size.width);
                int y = rand.nextInt(size.height);
                int w = 5+ rand.nextInt(50);
                int h = 5+ rand.nextInt(50);
                if (evt.getKeyChar() == 'r') {
                    figs.add(new Rect(x,y, w,h));
                    } 
                else if (evt.getKeyCode() == KeyEvent.VK_DOWN || evt.getKeyCode() == KeyEvent.VK_LEFT || evt.getKeyCode() == KeyEvent.VK_RIGHT || evt.getKeyCode() == KeyEvent.VK_UP ) {
                    if (figs.size() > 0){
                        int dx = 0;
                        int dy = 0;
                        if(evt.getKeyCode() == KeyEvent.VK_DOWN) dy = 2;
                        else if (evt.getKeyCode() == KeyEvent.VK_UP){ dy = -2;}
                        else if (evt.getKeyCode() == KeyEvent.VK_RIGHT) dx = 2;
                        else if (evt.getKeyCode() == KeyEvent.VK_LEFT) dx = -2;
                            
                        
                        Figure fig = figs.get(figs.size() -1);
                        fig.mov(dx,dy);
                        figs.set(figs.size() -1, fig);


                    }
                
                }
                repaint(); 
                
                }
                
            }
        );

        this.setTitle("Figures");
        this.setSize(350, 350);
    }

    public void paint (Graphics g) {
        super.paint(g);
        for (Figure fig: this.figs) {
            fig.paint(g);
        }
    }

    
}

标签: java

解决方案


你犯了一些奇怪的错误。不要扩展 JFrame 在这种情况下它是没有意义的。

这是一个开始。您可能应该使用键侦听器以外的其他东西,并改为为输入映射执行操作。

class ListFrame {
    ArrayList<Figure> figs = new ArrayList<Figure>();
    Random rand = new Random();

    ListFrame () {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        JPanel custom = new JPanel(){
           @Override
           public void paintComponent(Graphics g) {
               super.paint(g);
               for (Figure fig: figs) {
                  fig.paint(g);
               }
           }
           @Override
           public Dimension getPreferredSize(){
               //you custom component should know it's preferred size.
               return new Dimension(350, 350); 
           } 
        };

        frame.addKeyListener (
            new KeyAdapter() {
                public void keyPressed (KeyEvent evt) {
                Dimension size = custom.getSize();
                
                int x = rand.nextInt(size.width);
                int y = rand.nextInt(size.height);
                int w = 5+ rand.nextInt(50);
                int h = 5+ rand.nextInt(50);
                if (evt.getKeyChar() == 'r') {
                    figs.add(new Rect(x,y, w,h));
                    } 
                else if (evt.getKeyCode() == KeyEvent.VK_DOWN || evt.getKeyCode() == KeyEvent.VK_LEFT || evt.getKeyCode() == KeyEvent.VK_RIGHT || evt.getKeyCode() == KeyEvent.VK_UP ) {
                    if (figs.size() > 0){
                        int dx = 0;
                        int dy = 0;
                        if(evt.getKeyCode() == KeyEvent.VK_DOWN) dy = 2;
                        else if (evt.getKeyCode() == KeyEvent.VK_UP){ dy = -2;}
                        else if (evt.getKeyCode() == KeyEvent.VK_RIGHT) dx = 2;
                        else if (evt.getKeyCode() == KeyEvent.VK_LEFT) dx = -2;
                            
                        
                        Figure fig = figs.get(figs.size() -1);
                        fig.mov(dx,dy);
                        //You don't need to set the value. You modified it. 
                        //figs.set(figs.size() -1, fig);
                    }                
                }
                custom.repaint(); 
                
                }
                
            }
        );

        frame.setContentPane(custom);
        frame.pack();
        frame.setTitle("Figures");
        frame.setVisible(true);
    } 
}

推荐阅读