如何在JPanel上作为背景绘制网格线

3

我有一个问题。我在我的JFrame中使用了Gridbaglayout。其中一个组件是JPanel。

我想为我的JPanel绘制网格线作为背景。例如,在下面的程序中,它应该产生3条垂直和3条水平线,但它只显示2条垂直和2条水平线。最后一条线没有显示。

另一个问题是,似乎JPanel的大小比我设置的要大。我通过线的长度来注意到这一点,线的长度比JPanel的白色背景短。

  public class drawLayout extends JComponent 
    {

 public Dimension getPreferredSize() { 
  return new Dimension(600, 600); 
 }

 public int getY() { 
  return 0; 
 } 

 public int getX() { 
   return 0; 
    }

    @Override public void paintComponent(Graphics g)
    {
     g.setPaint(Color.GRAY);

            for (int i = 0; i <= getSize().width; i += 300) 
            {
               g2.drawLine(i, 0, i, getSize().height);
            }

            for (int i = 0; i <= getSize().height; i += 300) 
            {
               g2.drawLine(0,i, getSize().width, i);
            }
    } 
}

编辑:

http://www.freeimagehosting.net/image.php?1af16edc28.jpg

第一个问题已解决(在JPanel上显示了网格线)。 另一个问题让我感到困惑。如您所见,附加的图像中,当查看网格的长度时(标为红框),JPanel的大小似乎超过600。我该如何解决这个问题,使得网格线背景看起来漂亮,没有任何额外的白色空间超出网格线?

2个回答

3
如果您的JPanel大小为600,则其可用坐标仅从0到599。在600处的线将不会被绘制。
此外,任何边框和/或插入都将进一步减少可用空间。
更新:我有一些时间,所以我为您编写了应用程序。希望您能找到一些有用的提示。
public class Jessy extends JFrame {

   private static final int DRAWING_SIZE = 600;
   private static final int SUBDIVISIONS = 2;
   private static final int SUBDIVISION_SIZE = DRAWING_SIZE / SUBDIVISIONS;

   public Jessy() {
      setSize(800, 800);
      setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.gridx = 0;
      gbc.gridy = 0;
      JLabel drawingBoard = new JLabel("Drawing Board");
      gbc.anchor = GridBagConstraints.SOUTH;
      drawingBoard.setFont(new Font("Serif", Font.BOLD, 28));
      add(drawingBoard, gbc);
      JPanel panel = new JPanel() {
         @Override public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(Color.GRAY);
            for (int i = 1; i < SUBDIVISIONS; i++) {
               int x = i * SUBDIVISION_SIZE;
               g2.drawLine(x, 0, x, getSize().height);
            }
            for (int i = 1; i < SUBDIVISIONS; i++) {
               int y = i * SUBDIVISION_SIZE;
               g2.drawLine(0, y, getSize().width, y);
            }
         }          
      };
      panel.setPreferredSize(new Dimension(DRAWING_SIZE, DRAWING_SIZE));
      panel.setBackground(Color.WHITE);
      panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
      gbc.gridy++;
      gbc.anchor = GridBagConstraints.CENTER;
      add(panel, gbc);
      JButton saveDrawing = new JButton("SAVE DRAWING");
      gbc.gridy++;
      gbc.anchor = GridBagConstraints.NORTH;
      add(saveDrawing, gbc);
   }
   public static void main(String[] args) {
      (new Jessy()).setVisible(true);
   }
}

一些细节:

  • 我使用了边框来画外线,这样可以避免 "599" 的问题。
  • 我假设您希望内部有细分网格,因此我添加了一些管道,使其更加灵活和可配置。
  • 我注意到您的 paintComponents() 没有调用 super.paintComponents()。它应该调用!
  • 我使用了我认为是最少的代码来指定网格袋约束。少编码=少错误 :)
  • 我继承了一个 JPanel(按照您的要求),而不是 JComponent(按照您的代码)。区别似乎在于 JComponent 无法绘制其背景,因此最终变成了灰色。
  • 也许最重要的是,我使用 kruler 测量了我的 GUI:绘图组件在两个方向上都恰好为 600! :)

谢谢你的回答,Carl。我的JPanel看起来比600还要大。我没有使用边框或插图。 - Jessy
1
如果看起来比600大,但你没有看到第三行,那么额外的空间就在面板外面。要么你设置了ipadx/ipady为非0,要么填充为NONE,但有其他组件强制使你的单元格变大。测试这个最简单的方法是设置面板的背景颜色,这样你就可以看到它的边缘在哪里。 - Carl Smotricz
1
仅为完整起见,插入物也可以在GridBagConstraints中设置。但这并不能解释您的面板为什么超过了600。 - Carl Smotricz
我刚刚看了你的屏幕截图,没有找到说明我所看到的内容的解释。请展示你的GUI代码!Pastebin 可能是一个不错的分享方式:http://pastebin.com/ - Carl Smotricz
1
+1 鼓励你多花时间。@Jessy,你应该点击绿色复选框接受这个答案。对于为你做了这么多工作的人来说,这是礼貌的表现。 - Andres

0

你正在将 i 增加 300。经过两次循环,i 等于 600,并退出了 for 循环。 尝试将您的维度设置为 601 或增加 299。您还可以在比较中使用 width+1 和 Height+1。


谢谢Andres。我已经将维度增加到了601,并显示了最后一行。但我想知道,因为我将限制设置为i <= getSize().height,这意味着它应该在循环中运行三次,也就是说第三行应该被绘制。 - Jessy
Carl在下面说了,但是600的维度给出了从0到599的范围。因此,在第三次迭代中,i = 600,width = 599。因此,i > width。 - Andres
谢谢Andres。还有一个问题,为什么JPanel看起来更大?我怎样才能让它只显示600 X 600的确切大小? - Jessy
1
将维度保留在600,并在您的paintComponent代码末尾添加以下两行: g2.drawLine(getSize().width, 0, getSize().width, getSize().height); g2.drawLine(getSize().height, 0, getSize().height, getSize().width); - Andres

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接