我一直在研究迷宮生成器/求解器程式。它作業得很好,但我在重構我的代碼時遇到了一個問題。
基本上,我曾經直接從另一個類呼叫繪制解決迷宮程序的方法,而不是呼叫paintComponent方法(或者更確切地說是repaint方法)。顯然這不是一個好的做法,在性能方面也不是令人滿意的,我試圖解決這個問題。
問題是,要繪制解決方案的子步驟,不同的求解器演算法需要不同型別和數量的引數。我可以將這些存盤在一個類中,然后呼叫paintComponent 方法,在該方法中我呼叫使用上述引數繪制子步驟的方法。
不幸的是,這意味著我必須創建一堆擴展 JPanel 的其他類,以便我可以存盤必要的集合和變數,以便我可以繪制一個特定的解決方案。
有沒有更好的方法來解決這個問題,還是我應該放棄并按照我提到的方式去做?
所以我想要做的是:
@Override
public void paintComponent(Graphics g){
super(g);
drawMaze(g);
switch(solverType) //Based on what solver is assigned to the maze it calls the proper method
{
case solver1:
solver1Drawer(g, additional arguments);
break;
case solver2:
solver2Drawer(g, different kind, and number of arguments);
break;
//Other cases, with other method calls
}
}
uj5u.com熱心網友回復:
有很多方法可以構建可以接受不同求解器和視圖的此類應用程式。我將嘗試演示一個非常基本的精簡版,以使其盡可能簡單。
為此,我們將使用求解器來計算特定形狀的周長并繪制解決方案。
首先,我們將定義一些介面,稍后會更清楚它們的使用:
interface Model{
boolean solve();
int solution();
boolean isSolved();
}
interface View{
void draw(Graphics g);
}
interface Solver {
Model getModel();
View getView();
}
利用這些介面我們定義的中號奧德爾的V IEW和? ontroller支持正方形的周長的計算。
該模型封裝了資訊(屬性和狀態)和邏輯:
class SquarePrimeterModel implements Model{
private final int edgeLength;
private int perimeter;
private boolean isSolved = false;
public SquarePrimeterModel(int edgeLength) {
this.edgeLength = edgeLength;
}
@Override
public boolean solve() {
perimeter = 4 * edgeLength;
isSolved = true;
return true;
}
@Override
public int solution() {
return perimeter;
}
@Override
public boolean isSolved() {
return isSolved;
}
//edgeLength is a unique property for this model
public int getEdgeLength() {
return edgeLength;
}
}
視圖的職責,顧名思義就是生成視圖:
class SquarePrimeterView implements View{
private final static int xOffset = 50, yOffset = 50, GAP = 20;
private final SquarePrimeterModel model;
public SquarePrimeterView(SquarePrimeterModel model) {
this.model = model;
}
@Override
public void draw(Graphics g) {
if(model.isSolved()){
g.drawRect(xOffset, yOffset, model.getEdgeLength(), model.getEdgeLength());
String text = "Edge =" model.getEdgeLength() " Perimiter =" model.solution();
int yPosition = yOffset model.getEdgeLength() GAP;
g.drawString(text, xOffset, yPosition);
}
}
}
控制器構造、配置和管理模型和視圖:
class SquarePrimeterController implements Solver{
private final SquarePrimeterModel model;
private final View view;
public SquarePrimeterController(int edgeLength) {
model = new SquarePrimeterModel(edgeLength);
view = new SquarePrimeterView(model);
}
@Override
public Model getModel() {
return model;
}
@Override
public View getView() {
return view;
}
}
如果我們需要另一個求解器,例如,一個求解器來計算三角形的周長,我們只需撰寫 TriangelPrimerController、TriangelPrimerModel 和 TriangelPrimerView,與 SquarePrimeter 類非常相似。
我們需要的最后一段代碼是使用SquarePrimeterController以下內容的應用程式:
public class SwingMVCSolveController {
public SwingMVCSolveController() {
Solver solver = new SquarePrimeterController(150);//todo: select solver by gui
solver.getModel().solve(); //todo start solve by gui
new MainView(solver.getView());
}
public static void main(String[] args) {
new SwingMVCSolveController();
}
}
class MainView extends JPanel {
private static final Dimension size = new Dimension(400, 400);
private final View solverView;
public MainView(View view) {
solverView = view;
createAndShowGui();
}
private void createAndShowGui() {
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add (this);
frame.pack();
frame.setVisible (true);
}
@Override
public Dimension getPreferredSize() {
return size;
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
solverView.draw(g);
}
}
顯然Solver solver = new SquarePrimeterController(150);可以更改為Solver solver = new TrianglePrimeterController(150);或 的任何其他實作Solver。
完整的可運行代碼可在此處獲得
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/374391.html
上一篇:我可以使用多個網格嗎?
