二维数组网格 - 将字符放在每个单元格的中间

2D array grid - placing character in the middle of each cell

有一个应该代表地图的二维字符数组

char test[][]={{'A','B','C'},{'D','E','F'},{'G','H','I'};

如何使用 java.awt 库创建一个 3x3 网格,使每个字符位于每个单元格的中心?

下面的代码给了我一个网格,但我仍然不确定如何将每个字符放在每个单元格的中心。

int sideLength=115;
int distance=sideLength*3;
int i=0;
int j=0;

for ( int x=90; x<=distance; x+=sideLength )
{
    for( int y=30; y<=distance; y+=sideLength )
    {

       g.drawRect(x,y,sideLength, sideLength);
       g.drawString(Character.toString(test[i][j]), sideLength/2, sideLength/2);

    }  
    i++;
    j++;
}          

这段代码给出了这个输出

虚无缥缈...

好的,JLabels 和 Borders

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;

public class Test {

  public static void main(String[] args) {
    new Test();
  }

  public Test() {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        JFrame frame = new JFrame();
        frame.add(new TestPane());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    });
  }

  public class TestPane extends JPanel {

    public TestPane() {
      setBorder(new EmptyBorder(10, 10, 10, 10));
      setLayout(new GridLayout(0, 3));
      String test[][]={{"A","B","C"},{"D","E","F"},{"G","H","I"}};
      Border paddingBorder = new EmptyBorder(50, 50, 50, 50);
      for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
          JLabel label = new JLabel(test[row][col]);
          label.setVerticalAlignment(JLabel.CENTER);
          label.setHorizontalAlignment(JLabel.CENTER);

          Border edgeBorder = new MatteBorder(
                  1, 
                  1, 
                  row == 2 ? 1 : 0, 
                  col == 2 ? 1 : 0, 
                  Color.BLACK);
          label.setBorder(new CompoundBorder(edgeBorder, paddingBorder));

          add(label);
        }
      }
    }

  }

}

这个主题有很多变体,但它代表了最简单的方法

自定义绘画路线...

如果您想遵循自定义绘画路线,那么您将需要更好地了解字体的实际工作原理。

我建议从 Working with Text APIs 开始以获得基本的理解。

接下来,您将正确递增 ij 属性。 j 需要在呈现每一列之前重置,并且应该为每一行递增。

就我个人而言,我会反过来做,您使用每个 row/column 的索引从数组中获取值,然后根据当前位置计算 x/y 位置row/column 索引,但这就是我。

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

public class Test {

  public static void main(String[] args) {
    new Test();
  }

  public Test() {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        JFrame frame = new JFrame();
        frame.add(new TestPane());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    });
  }

  public class TestPane extends JPanel {

    String test[][] = {{"A", "B", "C"}, {"D", "E", "F"}, {"G", "H", "I"}};

    public TestPane() {
    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(90 + (115 * 4), 30 + (115 * 4));
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      int sideLength = 115;
      int distance = sideLength * 3;
      int i = 0;

      for (int x = 90; x <= distance; x += sideLength) {
        int j = 0;
        for (int y = 30; y <= distance; y += sideLength) {

          g.drawRect(x, y, sideLength, sideLength);

          FontMetrics fm = g.getFontMetrics();
          int yPos = y + ((sideLength - fm.getHeight()) / 2) + fm.getAscent();
          int xPos = x + ((sideLength - fm.stringWidth(test[i][j])) / 2);

          g.drawString(test[i][j], xPos, yPos);
          j++;
        }
        i++;
      }
    }

  }

}

你很接近,但我会稍微重构你的循环。不是迭代距离,而是迭代数组中的索引。然后使用数组索引导出位置。

char[][] test = {{'A','B','C'}, {'D','E','F'}, {'G','H','I'}};

int sideLength=115;

for (int i = 0; i < test.length; i++) {
    int x = 90 + sideLength * i;
    for (int j = 0; j < test[j].length; j++) {
        int y = 30 + sideLength * j;

        g.drawRect(x, y, sideLength, sideLength);
        g.drawString(
            Character.toString(test[i][j]), 
            x + sideLength / 2, 
            y + sideLength / 2);

    }  
}