0

シミュレーション モデルの内部状態の変更に伴う GUI の更新に問題があります。クラス シミュレータは、特定のステップ数だけ実行されます。すべてのステップで、コンピューターの内部状態が変化します。その後、Gui は通知を受け取り、現在の状態のテキストを含むコンピューターのグラフィカル表現を再描画する必要があります。残念ながら、以下に詳述するクラスでは、GUI はシミュレーション実行の最後のステップの後にのみ変更を更新します。オブザーバー (コンピューター) とオブザーバブル (GUICanvas) パターンを使用しています。シミュレーションの中間ステップで GUI が再描画されないというのは、何が間違っているのでしょうか?

public class NwSim {


   public NwSim() {
   }

   public static void main(String[] args) {
       JFrame frame;
       Simulator simulator = new Simulator();    
       canvas = new GUICanvas();         //create gui  canvas, which paints guy computers
       canvas.setBackground(Color.white);
       contentPane.add(canvas, BorderLayout.CENTER);
       frame.pack();
       frame.setVisible(true);
   simulator.simulate();
   }
}

//represents the controller in the simulation
public class Simulator {
List<Computer> computers;
private int simulationSteps;

public Simulator()
    simulationSteps = 200;
              computers = new ArrayList<Computer>();


    public void simulate() {
        for(int step = 0; step < simulationSteps; step++) {
        for(Computer computer : computers) {
        computer.tick()
    }
    }
    }

    public Computer createComputer() {
    Computer computer = new Computer();
    computers.add(computer)
    }
}



public class Computer extends Observable {

    public void tick {
    ….. // update field state of the computer
        if (state.stateChanged()) {
            setChanged();
            notifyObservers();    //notify observer- gui canvas that the state of computer has changed and it is time to repaint guiComputers 

        }
 }

 public string getState() {
return state;
 }
}

public class GUIComputer  {

 private static final long serialVersionUID = 1L;
 private int width;
 private int height;   
 private Image image;
 private Computer computer; 


 public GUIComputer(int x, int y, Computer computer component, Image image) {
     this.computer = computer;
     setX(x);
     setY(y);
     this.image = image;
     width = image.getWidth(null);
     height = image.getHeight(null);
 }


 @Override
 public void drawGuiComputer(Graphics g){
        g.drawImage(image, getX(), getY(), null);
        Graphics2D g2 = (Graphics2D)g;
        g2.drawString(computer.getState().toString(), getX() + 20, getY()    // repaint the state for each guiComputer taken from Computer 
                + height + 10);
}
}

public class GUICanvas extends JPanel implements  Observer { 

//
private List<GUIComputer> guiComputers;

public GUICanvas(Simulator simulator)  {
     this.guiComputers = new ArrayList<GUIComputer>();
    // create guy computers using method createGuiComputer below , code omitted
}

public createGuiComputer(Transferable transferable, Point dropPoint, Computer computer)  {
 Image image = Toolkit.getDefaultToolkit().getImage("images/" + imageName);
        Computer computer = simulator.createComputer();
                        GUIComputer guiComputer = new   GUIComputer(dropPoint.x, dropPoint.y, computer, image);
                         guiComputers.add(guiComputer);  
                         guiComputer.addObserver(this);

}

    @Override
     public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;      
            if (!GuiComputers.isEmpty()) {
                    for(GUIComputer guiComputer : guiComputers) {
                // redraw guiComputer
                            guiComputer.drawGuiComputer(g);
                        }
            }
}

    @Override
    public void update(Observable o, Object o1) {
    for(final GUIComputer guiComputer : guiComputers) {
                 if(guiComputer.getComputer().equals(o)) {  
                  //if update requested by Computer object then update gui, redrawing all guiComputers
                  revalidate();
                  repaint();
              }
    }
}
}
4

2 に答える 2

2

イベント ディスパッチ スレッドまたは EDT を、イベント スレッドで実行されている実行時間のかかるコードと結び付けている可能性があります。

public void simulate() {
    for(int step = 0; step < simulationSteps; step++) {
      for(Computer computer : computers) {
        computer.tick()
      }
    }
}

これを解決するには、 SwingWorkerまたはその他のバックグラウンド スレッドを使用してみてください。

于 2012-02-24T20:10:41.300 に答える