java如何在绘制线条时向JPanel添加背景网格?
我正在开发一个绘图工具,用户可以在JPanel
上画一条线
他将选择一个起点,然后将这条线拖动到终点以创建这条线
请注意,这里使用Java Point
类来定义每个点的坐标
下面是此场景中使用的简单代码:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DrawLine extends JPanel {
private MouseHandler mouseHandler = new MouseHandler();
private Point p1 = new Point(0, 0);
private Point p2 = new Point(0, 0);
private boolean drawing;
public DrawLine() {
this.setPreferredSize(new Dimension(400, 200));
this.addMouseListener(mouseHandler);
this.addMouseMotionListener(mouseHandler);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(8,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
private class MouseHandler extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
drawing = true;
p1 = e.getPoint();
p2 = p1;
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
drawing = false;
p2 = e.getPoint();
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
if (drawing) {
p2 = e.getPoint();
repaint();
}
}
}
private void display() {
JFrame f = new JFrame("LinePanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new DrawLine().display();
}
});
}
}
我想做的是画一个每平方20像素的网格
用户将选择以厘米为单位的比例,例如,每20个像素将为50厘米
当用户在面板上绘图时,网格必须作为背景,以便他/她可以使用它来确定线的尺寸(以厘米为单位)
为了更清楚,在C#中,我使用了一个picturebox,分配了一个网格的背景图像,并用于在其上绘制,如下图所示:
# 1 楼答案
你可以在^{中绘制所有单元格
# 2 楼答案
我不确定这是否是最好的解决方案,但这对我很有效:
与其将500硬编码为循环的上限,不如将其作为JPanel的maxWidth和maxHeight
# 3 楼答案
理论上,你应该能够使用Pythagorean theorem来计算PPI (AKA DPI),它的变化如下
其中:
例如,通过
22"
的2560x1600
屏幕给出137
的ppi。问题是,获取屏幕的对角线大小有人建议你可以使用^{,但这是众所周知的
返回一个不正确的值(即在我的屏幕上,它返回
102
,而它应该返回137
)那么,该怎么办?当其他方法失败时,假装失败
下面的示例定义了一个96的DPI(这是一个非常古老的通用屏幕分辨率,Java/Swing使用它是基于这个分辨率的,不能说它现在是或不是,但它过去是)
下面定义了
5cmx5cm
单元格的网格,总宽度/高度为20cm
您可能会注意到,当您调整窗口大小时,网格不会更新,直到有足够的空间容纳新行/列,这是为了演示算法
通过更改绘制网格的
while-loop
,可以允许网格溢出视图的可见边界这一切的关键是,你不能把
SCREEN_DPI
变成你想要的任何东西。要进行打印预览,请将其更改为300
或72
或任何您想要的内容。因为它是一个“已知”值,所以可以相对容易地从一种分辨率转换为另一种分辨率下面是一个想法,计算屏幕的PPI,并更改
SCREEN_DPI
以匹配并查看结果;)所以呢?例如,将
SCREEN_DPI
更改为匹配现在你有了一个每厘米20像素的测量
基本上你需要知道多少像素代表一个厘米,然后你可以简单地从厘米转换为像素,然后再转换回来
1厘米=20像素,2厘米=40像素,3厘米=。。。诸如此类。我相信你可以看到数学是如何运作的