我正在尝试将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
答案 0 :(得分:2)
你正在混淆:MazePanel以及称为'canvas'的JPanel都是可以“绘制”的组件。当您显然尝试绘制'canvas'组件时,您正在调用类MazePanel中的paintComponent方法。我猜你想要的是绘制'画布'组件。
没有那么多进入Swing,我认为无论如何都要调用paintComponent方法是错误的。你应该做的是,实现你自己的JPanel子类,然后覆盖paintComponent方法。只要您想要重新绘制该组件,就可以调用名为“repaint”的方法。
在秋千中绘画:http://www.oracle.com/technetwork/java/painting-140037.html#swing