2013-10-22 267 views
2

我建立一個小型的國際象棋棋盤的戰術中心保持元件尺寸,這將是一個有趣的方式來對利益(編程和國際象棋)反思。與緩衝區

一個問題我目前面臨,雖然解決了,被保持的1的板寬比:1。

Board延伸JPanel。由於約束問題,我選擇維持棋盤的物理尺寸而不是渲染尺寸。這會在實際使用時導致更快的操作。

我想要什麼它看起來像,並取得了:

Horizontal buffer Vertical buffer

我實現這雖然看起來很hackish的並且是雙向飛碟標準代碼差的方式(謝謝基於雙向飛碟)。

public Frame() { 
    final JFrame frame = new JFrame("Chess"); 
    final JPanel content = new JPanel(new BorderLayout()); 
    final JPanel boardConfine = new JPanel(new BorderLayout()); 
    final Board board = new Board(); 

    boardConfine.addComponentListener(new ComponentAdapter() { 
     @Override 
     public void componentResized(ComponentEvent e) { 
      int min = Math.min(boardConfine.getWidth(), boardConfine.getHeight()); 
      int xBuffer = (boardConfine.getWidth() - min)/2; 
      int yBuffer = (boardConfine.getHeight() - min)/2; 
      board.setBounds(xBuffer, yBuffer, min, min); 

     } 

    }); 
    boardConfine.add(board, BorderLayout.CENTER); 
    content.setBackground(new Color(205, 205, 205)); 
    content.add(boardConfine, BorderLayout.CENTER); 

    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    frame.setContentPane(content); 
    frame.pack(); 
    frame.setVisible(true); 
} 

如上所示,我手動設置電路板的尺寸和位置。即使我已經詳盡地指出,這不應該做,但我找不到工作的解決方案。我需要電路板來填充最大可能區域,但仍保持寬高比。

如果有,你可以提供什麼建議(代碼或概念),我真的很感謝您抽出寶貴的時間來幫助我解決這個難題精英。

+0

如果您的主板開出的角球被定義爲任何寬度分鐘|高度,然後我沒有看到你的代碼的任何問題。 – TwoThe

+0

@TwoThe'雖然沒有佈局管理器是可以做到的,但如果可能的話,您應該使用佈局管理器。'我所做的是不使用佈局管理器。雖然我使用了邊界佈局,但是通過使用'null'佈局,這些方法可以實現相同的結果。因此這是不好的代碼。 – Obicere

回答

2

雖然不是完整的解決方案,下面的例子中縮放板以填充封閉容器的最小尺寸。調整框架大小以查看效果。

附錄:理想的解決方案是Creating a Custom Layout Manager,您可以訪問封閉容器的幾何圖形,並且setBounds()可以保持所需的1:1縱橫比。 GridLayout的變體可能是合適的。網格座標可以直接計算,如here所示。

test image

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

/** 
* @see https://stackoverflow.com/a/19531648/230513 
*/ 
public class Test { 

    private static class MyPanel extends JPanel { 

     private static final int N = 8; 
     private static final int TILE = 48; 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(N * TILE, N * TILE); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.gray); 
      int w = this.getWidth(); 
      int h = this.getHeight(); 
      int tile = Math.min(w, h)/N; 
      for (int row = 0; row < N; row++) { 
       for (int col = 0; col < N; col++) { 
        if ((row + col) % 2 == 0) { 
         g.fillRect(col * tile, row * tile, tile, tile); 
        } 
       } 
      } 
     } 
    } 

    private void display() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new MyPanel()); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test().display(); 
      } 
     }); 
    } 
} 
+0

感謝您的建議。正如OP中所述,我想避免這種類型的解決方案。事件發生時效率較低,而且難以維護。雖然謝謝! P.S:黑色正方形是左下角。 – Obicere

+0

德哦,感謝您的更正。我可以看到座標的問題。對於固定大小,請參閱此[示例](http://stackoverflow.com/a/2562685/230513)和[變體](http://stackoverflow.com/a/2563350/230513)。引用的例子[這裏](http://stackoverflow.com/a/7142109/230513)擴大了世界;那麼問題就變成了控制屬於主機OS的幀。 – trashgod