2014-01-20 158 views
0

我有點新搖擺。爲了學會正確使用API​​,我正在設計以下項目: 該項目是一個解決塊拼圖解算器滑塊拼圖類似於玩具商店中常見的高峯時間拼圖 - https://en.wikipedia.org/wiki/Rush_Hour_(board_game)除了特殊功能汽車。Gridbag佈局還是網格佈局?

通過將塊從板外區域拖動到板上,用戶指定拼圖的開始配置。用戶以同樣的方式指定結束目標配置,該配置指示用戶最初指定的一些(或全部)塊必須位於拼圖的末尾 - 結束配置可以僅使用某些塊指定,製作多種合法的結尾配置。

解決這個難題的算法已經完成 - 我只需要設計界面,我就陷入困境。爲了設計托盤,我使用了網格佈局。由於塊需要在某些位置輸入,我需要能夠將塊放置在網格中的特定單元格中並將它們移動。 'block'對象有四個屬性 - 它的高度,寬度,頂行和最左列(即,每個塊由其左上角尋址)。

我在這裏使用了建議(https://stackoverflow.com/questions/2510159/can-i-add-a-component-to-a-specific-grid-cell-when-a-gridlayout-is-used)作爲網格佈局。

現在我已經編程到java讀取.txt文件中的拼圖並且應該在屏幕上顯示它(我還沒有設計任何用戶可交互性)。

首先,這是我迄今爲止編寫的代碼。

public class SolverPuzzleGUI extends JFrame { 

//Specs from the puzzle. 
Board initBoard; 
ArrayList<Block> goalBlocks; 
LinkedList<Move> moveList; 

JLayeredPane layeredpane; 
JPanel Board; 
Dimension boardsize = new Dimension(400, 500); 
JPanel[][] panelHolder = new JPanel[5][4]; 

public SolverPuzzleGUI(Board startBoard, ArrayList<Block> startGoalBlocks, 
     LinkedList<Move> startMoveList) { 
    this.initBoard = startBoard; 
    this.goalBlocks = startGoalBlocks; 
    this.moveList = startMoveList; 


} // end constructor. 


//gives the actual simulation 

public void runSimulation() { 



    // Initalizing the main window. 
    setSize(500, 600); 
    setName("Solution"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setMinimumSize(getMinimumSize()); 



    //Using layered pane 
    layeredpane = new JLayeredPane(); 
    add(layeredpane); 
    layeredpane.setPreferredSize(boardsize); 

    layeredpane.setBackground(Color.YELLOW); 
    layeredpane.setVisible(true); 



    // adding the game tray 
    Board = new JPanel(); 
    layeredpane.add(Board, JLayeredPane.DEFAULT_LAYER); 
    Board.setLayout(new GridLayout(5, 4)); 

    // centering the game tray. 
    Board.setPreferredSize(boardsize); 
    Board.setMinimumSize(boardsize); 
    Board.setMaximumSize(boardsize); 

    Box box = new Box(BoxLayout.Y_AXIS); 
    box.add(Box.createVerticalGlue()); 
    box.add(Board); 
    box.add(Box.createVerticalGlue()); 

    add(box); 


    //Adding placeholders to the board for creating blocks 
    for (int i = 0; i < 5; i++) { 
     for (int j = 0; j < 4; j++) { 
      panelHolder[i][j] = new JPanel(); 
      panelHolder[i][j].setBackground(Color.DARK_GRAY); 

      Board.add(panelHolder[i][j]); 
      layeredpane.setLayer(panelHolder[i][j], JLayeredPane.DEFAULT_LAYER); 
      panelHolder[i][j].setVisible(false); 


     } // end 'j' for 
    } // end 'i' for 

    ArrayList<Block> initBlocks = initBoard.getBlocks(); 
    //int count = 0; //DEBUG 
    for (Block block : initBlocks) { 
     this.drawBlock(block); 
     //count++; 
     //if(count > 4) { break; } 
       } // end 'for' 


    Board.setBackground(Color.DARK_GRAY); 
    Board.setVisible(true); 

    setVisible(true); 
} // end 'run' 



private void drawBlock(Block block) { 
    Dimension blockSize = new Dimension(block.getWidth()*100, block.getHeight()*100); 
    System.out.println(blockSize.width); 
    System.out.println(blockSize.height); 

    JPanel screenBlock = new JPanel(); 

    screenBlock.setPreferredSize(blockSize); 
    screenBlock.setMinimumSize(blockSize); 
    screenBlock.setMaximumSize(blockSize); 
    screenBlock.setSize(blockSize); 

    screenBlock.setBackground(Color.BLUE); 
    screenBlock.setBorder(BorderFactory.createLineBorder(Color.BLACK)); 
    layeredpane.setLayer(screenBlock, JLayeredPane.MODAL_LAYER); 

    int leftRow = block.getRow(); 
    int leftCol = block.getColumn(); 


    panelHolder[leftRow][leftCol].setSize(blockSize); 
    panelHolder[leftRow][leftCol].setVisible(true); 
    panelHolder[leftRow][leftCol].add(screenBlock); 
    layeredpane.setLayer(panelHolder[leftRow][leftCol], JLayeredPane.MODAL_LAYER); 


    screenBlock.setVisible(true); 



}// end 'drawBlock' 






public static void main(String[] args) { 
    String file = "C:\\Users\\Tim\\Desktop\\init.from.handout.txt"; 
    String goal = "C:\\Users\\Tim\\Desktop\\goal.2.from.handout.txt"; 

    /* 
    A SolverPuzzle object is the object which actually solves the algorithm - 
    when the class is constructed, it takes the file path of the inital 
    configuration as an input, as well as the file path of the goal 
    configuration. It has the following fields: 

    A 'board' object which specifies the inital configuration of the board. 
    It contains an ArrayList of Block objects(Remember block objects store 
    the height and width of the block, as well as the address of the 
    top left corner of block) which specify the starting 
    blocks, an ArrayList of EmptySpace objects which specify the empty 
    spaces on the board, an ArrayList of Move objects, which contain 
    the legal moves of the configuration, and the height and width of 
    the tray (in this application, the tray will always be 5 x 4). 

    An ArrayList of Block objects which specify the ending configuration. 

    A LinkedList of Move objects which specify the shortest possible 
    list of Moves which brings the configuration to a position which 
    satisfies the goal position. A Move object has three fields - 
    The block object being moved, and the row and column of the 
    top left corner of the block in the new position. 


    */ 

    SolverPuzzle test; 
    try { test = new SolverPuzzle(file, goal); } 
    catch (IOException ex) { 
     System.out.println("IOException"); 
     return; 
    } 
    Board testBoard = test.getStartBoard(); 

    ArrayList<Block> testGoalBlocks = test.getGoalBlocks(); 
    LinkedList<Move> testMoveSolution = test.getMoveList(); 

    // testing the gui 
    SolverPuzzleGUI testGUI = new SolverPuzzleGUI(testBoard, testGoalBlocks, 
           testMoveSolution); 
    testGUI.runSimulation(); 

} 

} // end class 'SolverPuzzleGUI' 

這裏是當前輸出與期望輸出。

http://imgur.com/a/ykXXP

那麼具體的,我有兩個問題:

1 - 爲什麼圖像只顯示塊而不是整個區塊的左上方的角落?

2 - 繼續使用GridLayout還是切換到GridBagLayout會更好嗎?對於想你想要做

感謝

回答

1

GridBagLayout肯定是合適的。例如,您可以擴展組件以包含多個列或行 - 就像您想要的那樣。請查看java tutorials瞭解如何使用它們。

使用GridBagLayout時要記住的一個關鍵點是,您需要在每個組件之後重置Constraints,前提是它們對於該特定組件是唯一的。

而且 - 我無法分辨你只顯示左上角的意思 - 它看起來喜歡它給我看整個事情...

+0

的是,似乎有我有GridBagLayout的問題沒有辦法使網格成爲一個靜態大小 - 也就是說,我該如何做到這一點,因此它始終是一個5 x 4的網格,並且當我將移動應用到棋盤上時,網格不會添加或移除列。 另外,當我運行代碼時,它只顯示左上角。例如,中心塊應該跨越2列和2行,塊的左上角應該位於第一行/第一列。它僅顯示佔據第一行/第一列的1 x 1組件。 – newalchemy