java - 重新绘制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);
}
}
}
解决方案
你犯了一些奇怪的错误。不要扩展 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);
}
}
推荐阅读
- c++ - 如何检测内存分配/释放错误的对象?
- encoding - 我正在尝试使用 fmod 库。当我传递包含韩语的路径值时,输出“找不到文件”错误消息
- android - 底部栏位于导航栏后面的低位
- node.js - 带有 Node Js 的 Mongodb
- python - 用“;”在文本之间划分标签
- sql-server - 如何对 MSSQL 中的列值求和
- scala - 如何从另一个中减去一个 Scala Spark DataFrame(归一化到平均值)
- javascript - 谷歌图表中仪表图表的多个选项
- node.js - Facebook Graph API - 回发事件问题
- codeigniter - 如何在codeigniter中使图像上传可选?