0

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

基本上我发现 notifyObserver() 调用按预期工作。单击“创建”按钮后,迷宫将被打印出来。但是在 actionEvent 结束时,整个框架变黑了,我不知道为什么。

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

 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

4

1 回答 1

2

You are mixing things up: Both the MazePanel as well as the JPanel called 'canvas' are components that can be 'painted'. While you are apparently trying to paint the 'canvas' component, you are invoking the paintComponent method in your class MazePanel. I guess what you want is to paint the 'canvas' component.

Without being all that much into Swing, I think it is wrong to call the method paintComponent anyway. What you should do, is implementing you own subclass of JPanel and then override the paintComponent method. Whenever you want that component to be repainted, you call the method called 'repaint'.

Painting in Swing: http://www.oracle.com/technetwork/java/painting-140037.html#swing

于 2013-05-26T10:28:18.407 回答