Я пытаюсь создать окрашиваемую JPanel с опциональным отображением линии сетки. Для этого у меня есть пользовательская JPanel, которая создает другую JPanel, которая содержит только линии сетки. Таким образом, я могу показать / скрыть линии сетки, даже не удаляя то, что находится на холсте.
Кажется, все работает, за исключением некоторых странных проблем с выравниванием, которые я, кажется, могу определить. Когда я начинаю рисовать некоторые квадраты, они всего на несколько пикселей выше линий сетки. Как я могу исправить это так, чтобы обе панели отображались точно друг на друге?
Вот пример проблемы:
![An Example of the grid](https://i.stack.imgur.com/gVdDJ.png)
package com.carvethsolutions.guilib.customcomp;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* A custom component for displaying a grid
*/
public class GridCanvas extends JPanel implements MouseListener {
/**
* Width and height of the canvas, in pixels
*/
private int width, height;
/**
* How many pixels represent one square on the grid
*/
private int gridScale;
/**
* The separate panel that holds the grid lines
*/
private JPanel gridPanel;
private boolean gridLinesVisible = true;
/**
* Holds color selections
*/
private Paintbrush paintbrush;
public GridCanvas() {
super();
width = 500;
height = 500;
setupComponent();
}
public GridCanvas(int width, int height) {
super();
this.width = width;
this.height = height;
setupComponent();
}
/**
* Private function to prepare the component.
*/
private void setupComponent() {
gridScale = 50;
this.setPreferredSize(new Dimension(width,height));
this.setBackground(Color.WHITE);
this.addMouseListener(this);
gridPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Vertical Lines
for (int x = gridScale; x <= width; x += gridScale) {
g.drawLine(x, 0, x, height);
}
for (int y = gridScale; y <= height; y += gridScale) {
g.drawLine(0, y, width, y);
}
}
};
gridPanel.setVisible(gridLinesVisible);
gridPanel.setPreferredSize(this.getPreferredSize());
this.add(gridPanel);
this.setSize(gridPanel.getSize());
paintbrush = new Paintbrush(Color.black);
}
/**
* Enable or disable grid lines from appearing on the Canvas
*/
public void toggleGridlines() {
gridLinesVisible = !gridLinesVisible;
gridPanel.setVisible(gridLinesVisible);
}
/**
* Invoked when the mouse button has been clicked (pressed
* and released) on a component.
*
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
int x = e.getX() / gridScale;
int y = e.getY() / gridScale;
System.out.println("mouseClicked Event : (" + x + ", " + y + ")");
this.getGraphics().setColor(paintbrush.getColor());
this.getGraphics().fillRect(x * gridScale, y * gridScale, gridScale, gridScale);
}
/**
* Invoked when a mouse button has been pressed on a component.
*
* @param e
*/
@Override
public void mousePressed(MouseEvent e) {
}
/**
* Invoked when a mouse button has been released on a component.
*
* @param e
*/
@Override
public void mouseReleased(MouseEvent e) {
}
/**
* Invoked when the mouse enters a component.
*
* @param e
*/
@Override
public void mouseEntered(MouseEvent e) {
}
/**
* Invoked when the mouse exits a component.
*
* @param e
*/
@Override
public void mouseExited(MouseEvent e) {
}
}