2016-11-12 18 views
0

的状态和属性我有两个班,一个包含的主要方法,并调用被称为城市景观和另一个叫建立paint方法。Java的图形:如何使Java记住对象

我试图创建一个城市景观与5层楼的窗户是随机或关闭(灰色或黄色)。问题是每次调用repaint方法时,窗口都会随机更改。

我怎样才能使Java记大厦(即灯)的状态,使其在重绘方法叫他们不要更改(例如,当窗口大小)。

这里是城市景观类

import javax.swing.*; 
 
import java.awt.*; 
 

 
public class CityScape extends JPanel { 
 
    private Building building1 = new Building(this, new Rectangle(25, 300, 50, 250)); 
 
    private Building building2 = new Building(this, new Rectangle(125, 350, 100, 200)); 
 
    private Building building3 = new Building(this, new Rectangle(275, 250, 100, 300)); 
 
    private Building building4 = new Building(this, new Rectangle(425, 350, 50, 200)); 
 
    private Building building5 = new Building(this, new Rectangle(525, 400, 100, 150)); 
 

 

 
    public static void main(String[] args) throws InterruptedException { 
 
    JFrame frame = new JFrame("CITYSCAPE"); 
 
    frame.setSize(675, 600); 
 
    frame.setVisible(true); 
 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
 
    CityScape c = new CityScape(); 
 
    frame.add(c); 
 

 
    } 
 

 

 
    public void paint(Graphics g) { 
 
    super.paint(g); 
 
    Graphics2D g2d = (Graphics2D) g; 
 
    setBackground(g2d); 
 
    paintBuildings(g2d); 
 
    } 
 

 
    public void paintBuildings(Graphics2D g2d) { 
 
    building1.paint(g2d); 
 
    building2.paint(g2d); 
 
    building3.paint(g2d); 
 
    building4.paint(g2d); 
 
    building5.paint(g2d); 
 
    } 
 

 
    public void setBackground(Graphics2D g2d) { 
 
    g2d.setColor(new Color(255, 102, 25)); 
 
    g2d.fillRect(0, 0, 1000, 1000); 
 
    g2d.setColor(Color.DARK_GRAY); 
 
    g2d.fillRect(0, 550, 700, 700); 
 

 
    } 
 

 

 
}

,这里是建筑类:

import java.awt.*; 
 

 
public class Building { 
 

 
    private CityScape cityScape; 
 
    private Rectangle r; 
 

 
    public Building(CityScape cityScape, Rectangle r) { 
 
    this.cityScape = cityScape; 
 
    this.r = r; 
 
    } 
 

 
    public void paint(Graphics2D g2d) { //Draws the windows on the building (either with lights off or on) 
 
    int x = 0; 
 
    int y = 0; 
 
    for (x = 0; x < r.getWidth(); x = x + 25) { 
 
     for (y = 0; y < r.getHeight(); y = y + 25) { 
 
     if (randBool()) { 
 
      g2d.setColor(Color.YELLOW); 
 
      g2d.fillRect((int) r.getX() + x, (int) r.getY() + y, 25, 25); 
 
      g2d.setColor(Color.WHITE); 
 
      g2d.fillRect((int) r.getX(), (int) r.getY() + y, (int) r.getWidth(), 1); 
 
     } else { 
 
      g2d.setColor(Color.GRAY); 
 
      g2d.fillRect((int) r.getX() + x, (int) r.getY() + y, 25, 25); 
 
      g2d.setColor(Color.WHITE); 
 
      g2d.fillRect((int) r.getX(), (int) r.getY() + y, (int) r.getWidth(), 1); 
 
     } 
 
     g2d.fillRect((int) r.getX() + x, (int) r.getY(), 1, (int) r.getHeight()); 
 
     } 
 
    } 
 
    g2d.fillRect((int) r.getX() + x, (int) r.getY(), 1, (int) r.getHeight()); 
 
    } 
 

 

 

 

 
    public static boolean randBool() { 
 
    return Math.random() < 0.5; 
 
    } 
 

 

 
}

谢谢

回答

0

你无法控制的喷漆工艺(如你所提到的,如调整大小),这将重绘的原因很多。

相反,你需要让这个什么画是每次都一样。你可以这样做,所以Building总是以同样的方式创建。

或者,你可以绘制BuildingBufferedImage使用BufferedImage::createGraphics()获得Graphics2D,是一定要保持一个参考BufferedImage你画,然后绘制BufferedImageJPanel使用Graphics::drawImage()来。

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.drawImage(myBuilding.getImg(), x, y, null); 
} 

注意:图纸BufferedImage,其中myBuildingBuilding实例的

public class Building { 

    private CityScape cityScape; 
    private Rectangle r; 
    private BufferedImage img; 

    public Building(CityScape cityScape, Rectangle r) { 
     this.cityScape = cityScape; 
     this.r = r; 
     this.img = draw(); 
    } 

    private BufferedImage draw() { 
     BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
     // you will need to set width and height! 

     Graphics2D g2d = img.createGraphics(); 
     // draw the image as before, but to the BufferedImage this time 

     return img; // image of the buildings 
    } 

    public BufferedImage getImg() { 
     return this.img; // returns the BufferedImage 
    } 

    private static boolean randBool() { 
     return Math.random() < 0.5; 
    } 
} 

示例在具有JPanel和任何非顶层容器(例如JFrame是一个顶层容器),则应该覆盖paintComponent()而不是paint()paintComponents()s

Swing程序应该重写paintComponent(),而不是覆盖 paint()。虽然API允许的话,一般不存在理由 覆盖paintBorder()paintComponents()(如果你这样做,确保 你知道你在做什么!)。这种保理可以使 程序更容易地覆盖他们需要延伸的部分。例如,这解决了之前提到的AWT问题 ,其中调用super.paint()失败阻止任何 轻量级子项出现。

见:Difference between paint, paintComponent and paintComponents in SwingPainting in AWT and Swing