我将重写下面的类来使用构造函数并做一些更聪明的事情(而不是像方法那样的四个producer() - 所以不要担心。
目前,我遍历这四个数组列表,然后将对象绘制到JPanel上。在大约2-3000个对象之后,这可能导致一些显着的延迟。
我可以使用什么作为这些数组列表的替代?将某些类型的序列化转换为JSON / XML吗?在我的专业编码(而不是这个简单的侧面项目)中,我使用一个庞大的系统,使用DataNucleus将模型类转换为SQL中的表结构 - 我觉得这对我有趣的项目来说将是一个巨大的过度杀伤力。想法?
public class Life {
PlayPanel panel;
public int prodSeed;
public int herbSeed;
public int predSeed;
public int decoSeed;
public ArrayList<Producer> prodStore = new ArrayList<Producer>();
public ArrayList<Herbivore> herbStore = new ArrayList<Herbivore>();
public ArrayList<Predator> predStore = new ArrayList<Predator>();
public ArrayList<Decomposer> decoStore = new ArrayList<Decomposer>();
public Life() {
}
public void setPanel(PlayPanel p) {
panel = p;
}
public void producers() {
for(int j = 0; j < prodSeed; j++) {
Producer p = new Producer(panel.life);
prodStore.add(p);
}
panel.producerPaint = true;
}
public void herbivores() {
for(int j = 0; j < herbSeed; j++) {
Herbivore h = new Herbivore(panel.life);
herbStore.add(h);
}
panel.herbivorePaint = true;
}
public void predators() {
for(int j = 0; j < predSeed; j++) {
Predator p = new Predator(panel.life);
predStore.add(p);
}
panel.predatorPaint = true;
}
public void decomposers() {
for(int j = 0; j < decoSeed; j++) {
Decomposer d = new Decomposer(panel.life);
decoStore.add(d);
}
panel.decomposerPaint = true;
}
public void beginAction() {
for (int j = 0; j < prodStore.size(); j++) {
prodStore.get(j).behavior();panel.repaint();
}
for (int j = 0; j < herbStore.size(); j++) {
herbStore.get(j).behavior();panel.repaint();
}
for (int j = 0; j < predStore.size(); j++) {
predStore.get(j).behavior();panel.repaint();
}
for (int j = 0; j < decoStore.size(); j++) {
decoStore.get(j).behavior();panel.repaint();
}
//Use booleans between these for loops to not repaint an extra amount of action
}
JPanel类中的paintComponent方法非常痛苦:
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(producerPaint == true) {
//int j = 0;
while(j < life.prodStore.size()) {
g.setColor(new Color(19,145,14));
g.fillOval(life.prodStore.get(j).getxAxis(), life.prodStore.get(j).getyAxis(), life.prodStore.get(j).getxSize(), life.prodStore.get(j).getySize());
j++;
}
j=0;
}
if(herbivorePaint == true) {
//int j = 0;
while(j < life.herbStore.size()) {
g.setColor(new Color(228,226,158));
g.fillOval(life.herbStore.get(j).getxAxis(), life.herbStore.get(j).getyAxis(), life.herbStore.get(j).getxSize(), life.herbStore.get(j).getySize());
j++;
}
j=0;
}
if(predatorPaint == true) {
//int j = 0;
while(j < life.predStore.size()) {
g.setColor(new Color(207,87,87));
g.fillOval(life.predStore.get(j).getxAxis(), life.predStore.get(j).getyAxis(), life.predStore.get(j).getxSize(), life.predStore.get(j).getySize());
j++;
}
j=0;
}
if(decomposerPaint == true) {
//int j = 0;
while(j < life.decoStore.size()) {
g.setColor(Color.white);
g.fillOval(life.decoStore.get(j).getxAxis(), life.decoStore.get(j).getyAxis(), life.decoStore.get(j).getxSize(), life.decoStore.get(j).getySize());
j++;
}
j=0;
}
}
作为一个相关的旁注:当我完成这段代码时,我将重新使用布尔值(项目是一两年前,在我知道自己在做什么之前)!
答案 0 :(得分:2)
在组件上绘制许多项目不是问题,但不应该在paintComponent
内部发生。你想要做的是有一个单独的图像(例如BufferedImage
),在该图像上绘制,然后你的paintComponent
仅负责将该图像绘制到JPanel上。因此,您的用户并未逐一看到所有这些东西。他们只看到最终产品。
搜索“Java中的双缓冲”以获得有关此想法的精彩演示。
对于数据结构,保留4个列表很好,但您可能希望拥有更多抽象绘图实用程序,这些实用程序在所有对象之间共享。例如,除了Color之外,绘制它们的方式大致相同,因此创建一个绘制方法,接受超类(例如BiologyObject
)到任何子类(例如Producer
) ,Decomposer
等)作为参数。如果这没有意义,请告诉我。
更新:正确的方法来绘制到JPanel
private BufferedImage image;
public MyClass() {
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_ARGB);
}
public void paintOntoImage() {
//here is where you would draw all the things that you currently have in your paintComponent method
Graphics2D g = (Graphics2D) image.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, WIDTH, HEIGHT);
//now you can call "g.fillOval" or any other methods on "g"
}
public void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
}