2013-10-22 228 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