动作事件后的黑框和许多notifyObservers

时间:2013-05-26 08:16:16

标签: java swing model-view-controller observer-pattern

我正在尝试将MVC和Observer模式实现到我的java应用程序中。我有一个创建迷宫并解决它的应用程序。

基本上我发现notifyObserver()调用正在按预期工作。点击按钮后,迷宫即被打印"创建"。但是在行动结束时,整个框架变黑了,我不知道为什么。

查看面板对象的有趣部分:

 public class MazePanel extends JPanel implements Observer {

 .....some instance vars ect.....

    public void buildFrame(){

    // create the frame
    JFrame frame = new JFrame("Labyrinth Solver");   

    // create the JPanel
    canvas = new JPanel();
    canvas.setBorder(BorderFactory.createEmptyBorder(1000, 1000, 1000, 1000));
    canvas.setPreferredSize(new Dimension(getDimension()*zoom, getDimension()*zoom));

    // add the canvas to the frame and make it visible
    frame.add(canvas);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true); 
    frame.setResizable(false);
    frame.setBackground(Color.black);
}

@Override
protected void paintComponent(Graphics g){

    super.paintComponent(g);

    if(mode.equals("create")) {
            g.setColor(Color.white);
    }
    g.fillRect(curCoordinate.getX()*zoom, curCoordinate.getY()*zoom, 1*zoom, 1*zoom );
}

@Override
public void update(Observable observable, Object o) {

    curCoordinate = (Coordinate)o;
    paintComponent(canvas.getGraphics());

    try {
        Thread.sleep(getSpeed());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

通过动作事件看我的控制者:

public class MazeController {
 private MazeModel model;
 private MazeView view;
 private MazePanel mazePanel;
 private Builder mazeBuilder;

 public MazeController(MazeModel model, MazeView view) {
    this.model = model;
    this.view = view;

    mazePanel = new MazePanel();

    // Create Gui
    view.createAndShowGUI();

    // Add Listeners
    view.addChangeSpeedListener(new SpeedChangeAction());
    view.addCreateListener(new CreateActionListener());
}


private class CreateActionListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {

        // Configure the MazePanel object
        mazePanel.setMode("create");
        mazePanel.setZoom(view.getZoom());
        mazePanel.setDimension(view.getDimension());
        mazePanel.setSpeed(view.getSpeed());

        // Build panel
        mazePanel.buildFrame();

        // Get Build Type
        String createAlgorithm = view.getCreateAlgorithm();

        // Build selected maze
        if (createAlgorithm.equals("Depth-First")) {
            mazeBuilder = new DepthFirstSearch(model, view.getDimension());
        } 

        // Register observer
        mazeBuilder.registerObserver(mazePanel);


        // Build Maze
        mazeBuilder.build();

        // print data strucutre as array if debugging is enabled
        if(view.getDebug()){
            model.printAsArray();
        }

    }
}

实际上代码也可以在这里找到:https://github.com/do3meli/Labyrinth/tree/MVC/src/main/java/ch/zhaw/labyrinth

1 个答案:

答案 0 :(得分:2)

你正在混淆:MazePanel以及称为'canvas'的JPanel都是可以“绘制”的组件。当您显然尝试绘制'canvas'组件时,您正在调用类MazePanel中的paintComponent方法。我猜你想要的是绘制'画布'组件。

没有那么多进入Swing,我认为无论如何都要调用paintComponent方法是错误的。你应该做的是,实现你自己的JPanel子类,然后覆盖paintComponent方法。只要您想要重新绘制该组件,就可以调用名为“repaint”的方法。

在秋千中绘画:http://www.oracle.com/technetwork/java/painting-140037.html#swing