背景描述
在使用word办公软件的时候,我们会见到标尺,因为在文件导出打印的时候,可能会有很苛刻的要求,有了标尺,用户能够更直观的设计使用word。
功能摘要
在使用JavaFx开发的时候,不能调用Slider来当标尺使用,当然网上关于JavaFx的资源比较匮乏,这里我也是参考了网上的一点思路,自制了一个标尺厘米尺,使用画图的方式,在Group组件里画图完成的,因为这是要根据屏幕的dpi去计算英寸,从而得到厘米来展示的。
使用公式
像素与英寸之间的关系:
像素单位=英寸 * dpi
英寸与厘米之间的关系:
1英寸=2.54厘米
代码实现
import javafx.scene.Group;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Screen;
/**
* @author Fellon
* TODO 标尺工具类,制作厘米的垂直标尺和水平标尺 2020/12/2
*/
public class RulerUtil {
/****************************************************************
* TODO 像素单位=(厘米*dpi)/2.54
****************************************************************
****************************************************************/
public static final int RULER_WIDTH = 20; // 标尺宽度
public static final String FONT_FAMILY = "Microsoft YaHei"; // 字体样式
public static final int FONT_SIZE = 10; // 字体的大小
public static final int TEXT_LAYOUT = 10; // 文本距边界的位置
public static final double SCALE = 2.54; // 1英寸=2.54厘米
public static final int GAP = 50; // 容器内的边距产生的误差,防止宽高一直在变化
/**
* TODO 水平方向上的标尺
* @param groupHRuler
*/
public void makeHorizontalRuler(Group groupHRuler, double width) {
width = width - GAP;
Rectangle ruler = new Rectangle(0, 0, width, RULER_WIDTH);
ruler.setFill(Color.WHITE);
ruler.toBack();
groupHRuler.getChildren().add(ruler);
// 计算宽度共有多少厘米
double sceneDPI = this.getSceneDPI();
int widthCM = new Double(width / sceneDPI * SCALE).intValue();
for (int i = 0; i < widthCM * 2; i ++) {
// 如果为整厘米上
if (i % 2 == 0) {
// 添加文字
Text text = new Text(String.format("%3d", i / 2));
text.setLayoutX(this.calcPxByCm(i / 2.0));
text.setLayoutY(TEXT_LAYOUT);
text.toFront();
this.setFontAndColor(text);
groupHRuler.getChildren().add(text);
// 绘制 线
Line line = new Line();
line.setStartX(this.calcPxByCm(i / 2.0));
line.setEndX(this.calcPxByCm(i / 2.0));
line.setStartY(6);
line.setEndY(18);
line.setFill(Color.BLACK);
line.toFront();
groupHRuler.getChildren().add(line);
} else {
Line line = new Line();
line.setStartX(this.calcPxByCm(i / 2.0));
line.setEndX(this.calcPxByCm(i / 2.0));
line.setStartY(12);
line.setEndY(18);
line.setFill(Color.BLACK);
line.toFront();
groupHRuler.getChildren().add(line);
}
}
}
/**
* TODO 垂直方向上的标尺
* @param groupVRuler
*/
public void makeVerticalRuler(Group groupVRuler, double height) {
height = height - GAP;
Rectangle ruler = new Rectangle(0, 0, RULER_WIDTH, height);
ruler.setFill(Color.WHITE);
ruler.toBack();
groupVRuler.getChildren().add(ruler);
// 计算高度共有多少厘米
double sceneDPI = this.getSceneDPI();
int heightCM = new Double(height / sceneDPI * 2.54).intValue();
for (int i = 0; i < heightCM * 2; i ++) {
if (i % 2 == 0) {
// 添加文字
Text text = new Text(String.format("%3d", i / 2));
text.setLayoutX(2);
text.setLayoutY(this.calcPxByCm(i / 2.0) + 10);
text.toFront();
this.setFontAndColor(text);
groupVRuler.getChildren().add(text);
// 绘制 线
Line line = new Line();
line.setStartX(6);
line.setEndX(18);
line.setStartY(this.calcPxByCm(i / 2.0));
line.setEndY(this.calcPxByCm(i / 2.0));
line.setFill(Color.BLACK);
line.toFront();
groupVRuler.getChildren().add(line);
} else {
Line line = new Line();
line.setStartX(12);
line.setEndX(18);
line.setStartY(this.calcPxByCm(i / 2.0));
line.setEndY(this.calcPxByCm(i / 2.0));
line.setFill(Color.BLACK);
line.toFront();
groupVRuler.getChildren().add(line);
}
}
}
/**
* TODO 设置字体的样式大小及颜色
* @param text
*/
private void setFontAndColor(Text text) {
text.setFont(Font.font(FONT_FAMILY, FONT_SIZE));
text.setFill(Color.BLACK);
}
private double calcPxByCm(double x) {
return x * this.getSceneDPI() / SCALE;
}
private double getSceneDPI() {
return Screen.getPrimary().getDpi();
}
}