mirror of
https://gitee.com/dromara/hutool.git
synced 2026-02-09 09:16:26 +08:00
add PrintUtil
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2025 Hutool Team and hutool.cn
|
||||
* Copyright (c) 2013-2026 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2026 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hutool.v7.swing;
|
||||
|
||||
import cn.hutool.v7.core.array.ArrayUtil;
|
||||
import cn.hutool.v7.core.lang.Console;
|
||||
import cn.hutool.v7.core.lang.builder.Builder;
|
||||
import cn.hutool.v7.core.util.ObjUtil;
|
||||
|
||||
import javax.print.PrintService;
|
||||
import javax.print.attribute.Attribute;
|
||||
import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.standard.*;
|
||||
import java.io.Serial;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 智能打印配置器:根据打印机能力动态构建 PrintRequestAttributeSet
|
||||
* <p>
|
||||
* 使用示例:
|
||||
* <pre><@code
|
||||
* PrintService printer = findPrinter("MyPrinter");
|
||||
* PrintRequestAttributeSet attrs = new SmartPrintConfigurator(printer)
|
||||
* .copies(2)
|
||||
* .a4Paper()
|
||||
* .landscape()
|
||||
* .duplex()
|
||||
* .monochrome()
|
||||
* .collated()
|
||||
* .highQuality()
|
||||
* .build();
|
||||
* }</pre>
|
||||
*/
|
||||
public class PrintAttributeBuilder implements Builder<PrintRequestAttributeSet> {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final PrintService printer;
|
||||
private final HashPrintRequestAttributeSet attributes;
|
||||
private final Set<Class<? extends Attribute>> supportedAttrs;
|
||||
|
||||
// 缓存支持的属性值(提升性能)
|
||||
private final Map<Class<? extends Attribute>, Object> supportedValuesCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param printer 打印机对象,不能为空
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public PrintAttributeBuilder(final PrintService printer) {
|
||||
this.printer = Objects.requireNonNull(printer, "printer 不能为空");
|
||||
this.attributes = new HashPrintRequestAttributeSet();
|
||||
this.supportedAttrs = Arrays.stream(printer.getSupportedAttributeCategories())
|
||||
.filter(Objects::nonNull)
|
||||
.filter(Attribute.class::isAssignableFrom)
|
||||
.map(c -> (Class<? extends Attribute>) c) // 安全转型
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
|
||||
// ------------------ 配置方法(链式调用) ------------------
|
||||
|
||||
/**
|
||||
* 设置份数(Copies)— 所有打印机均支持
|
||||
*
|
||||
* @param n 份数,至少为 1
|
||||
* @return this,用于链式调用
|
||||
*/
|
||||
public PrintAttributeBuilder copies(final int n) {
|
||||
attributes.add(new Copies(Math.max(1, n)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置作业名
|
||||
*
|
||||
* @param name 作业名,可为空字符串但不应为null
|
||||
* @return this,用于链式调用
|
||||
*/
|
||||
public PrintAttributeBuilder jobName(final String name) {
|
||||
attributes.add(new JobName(name, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制 A4 纸(若不支持则尝试 Letter 或忽略)
|
||||
*
|
||||
* @return this,用于链式调用
|
||||
*/
|
||||
public PrintAttributeBuilder a4Paper() {
|
||||
if (support(MediaSizeName.class)) {
|
||||
final MediaSizeName[] sizes = getSupportedValues(MediaSizeName.class);
|
||||
if (ArrayUtil.contains(sizes, MediaSizeName.ISO_A4)) {
|
||||
attributes.add(MediaSizeName.ISO_A4);
|
||||
} else if (ArrayUtil.contains(sizes, MediaSizeName.NA_LETTER)) {
|
||||
// 降级到 Letter(美标)
|
||||
attributes.add(MediaSizeName.NA_LETTER);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置横向打印方向
|
||||
* <p>
|
||||
* 如果打印机不支持横向打印,将输出警告信息并保持默认的纵向打印方向
|
||||
* </p>
|
||||
*
|
||||
* @return 当前PrintAttributeBuilder实例,支持链式调用
|
||||
*/
|
||||
public PrintAttributeBuilder landscape() {
|
||||
if (support(OrientationRequested.class) &&
|
||||
supportsValue(OrientationRequested.LANDSCAPE)) {
|
||||
attributes.add(OrientationRequested.LANDSCAPE);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置纵向打印模式(默认,通常无需显式调用)
|
||||
* <p>
|
||||
* 将打印方向设置为纵向模式,这是大多数打印任务的默认方向。
|
||||
* 如果打印机支持该方向,则会在打印属性中添加 PORTRAIT 方向设置。
|
||||
* </p>
|
||||
*
|
||||
* @return 当前 PrintAttributeBuilder 实例,支持链式调用
|
||||
*/
|
||||
public PrintAttributeBuilder portrait() {
|
||||
if (support(OrientationRequested.class) &&
|
||||
supportsValue(OrientationRequested.PORTRAIT)) {
|
||||
attributes.add(OrientationRequested.PORTRAIT);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 双面打印(若支持则启用,否则自动降级为单面并告警)
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public PrintAttributeBuilder duplex() {
|
||||
if (support(Sides.class)) {
|
||||
final Sides[] sides = getSupportedValues(Sides.class);
|
||||
if (Arrays.asList(sides).contains(Sides.DUPLEX)) {
|
||||
attributes.add(Sides.DUPLEX);
|
||||
} else if (Arrays.asList(sides).contains(Sides.TUMBLE)) {
|
||||
attributes.add(Sides.TUMBLE);
|
||||
} else {
|
||||
attributes.add(Sides.ONE_SIDED);
|
||||
}
|
||||
} else {
|
||||
attributes.add(Sides.ONE_SIDED);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制单面(覆盖可能的默认双面)
|
||||
*
|
||||
* @return this,用于链式调用
|
||||
*/
|
||||
public PrintAttributeBuilder oneSided() {
|
||||
attributes.add(Sides.ONE_SIDED);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 黑白打印(若支持彩色/黑白切换;否则保留默认)
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder monochrome() {
|
||||
if (support(Chromaticity.class) &&
|
||||
supportsValue(Chromaticity.MONOCHROME)) {
|
||||
attributes.add(Chromaticity.MONOCHROME);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 彩色打印(若支持)
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder color() {
|
||||
if (support(Chromaticity.class) &&
|
||||
supportsValue(Chromaticity.COLOR)) {
|
||||
attributes.add(Chromaticity.COLOR);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分套打印(collate)
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder collated() {
|
||||
if (support(SheetCollate.class) &&
|
||||
supportsValue(SheetCollate.COLLATED)) {
|
||||
attributes.add(SheetCollate.COLLATED);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 不分套
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder uncollated() {
|
||||
if (support(SheetCollate.class) &&
|
||||
supportsValue(SheetCollate.UNCOLLATED)) {
|
||||
attributes.add(SheetCollate.UNCOLLATED);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 高质量打印(若支持)
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder highQuality() {
|
||||
if (support(PrintQuality.class) &&
|
||||
supportsValue(PrintQuality.HIGH)) {
|
||||
attributes.add(PrintQuality.HIGH);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 草稿模式(省墨)
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder draftMode() {
|
||||
if (support(PrintQuality.class) &&
|
||||
supportsValue(PrintQuality.DRAFT)) {
|
||||
attributes.add(PrintQuality.DRAFT);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定进纸托盘为手动进纸
|
||||
*
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder manualTray() {
|
||||
if (support(MediaTray.class) &&
|
||||
supportsValue(MediaTray.MANUAL)) {
|
||||
attributes.add(MediaTray.MANUAL);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页码范围
|
||||
*
|
||||
* @param from 开始页码(包含)
|
||||
* @param to 结束页码(包含)
|
||||
* @return this,用于链式调用。
|
||||
*/
|
||||
public PrintAttributeBuilder pageRange(final int from, final int to) {
|
||||
// PageRanges 通常都支持
|
||||
attributes.add(new PageRanges(Math.max(1, from), Math.max(from, to)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建最终的属性集
|
||||
*/
|
||||
public PrintRequestAttributeSet build() {
|
||||
return ObjUtil.clone(this.attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印当前配置摘要(调试用)
|
||||
*/
|
||||
public void printSummary() {
|
||||
Console.log("🖨️ 打印配置摘要 [打印机: " + printer.getName() + "]");
|
||||
for (final Attribute attr : attributes.toArray()) {
|
||||
Console.log(" • " + attr.getCategory().getSimpleName() + " = " + attr);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrintAttributeBuilder{" +
|
||||
"printer=" + printer.getName() +
|
||||
", attributes=" + Arrays.toString(attributes.toArray()) +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* 快速获取支持的能力摘要
|
||||
*/
|
||||
public void printCapabilities() {
|
||||
Console.log("🔍 打印机能力检测: " + printer.getName());
|
||||
for (final Class<? extends Attribute> c : this.supportedAttrs) {
|
||||
final Object vals = printer.getSupportedAttributeValues(c, null, null);
|
||||
if (vals instanceof final Attribute[] arr) {
|
||||
Console.log(" ✅ " + c.getSimpleName() + ": " + Arrays.toString(arr));
|
||||
} else {
|
||||
Console.log(" ✅ " + c.getSimpleName() + " (值类型: " + (vals == null ? "null" : vals.getClass().getSimpleName()) + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean support(final Class<? extends Attribute> attrClass) {
|
||||
return supportedAttrs.contains(attrClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支持某个属性
|
||||
*
|
||||
* @param attrClass 属性类
|
||||
* @param <T> 属性类
|
||||
* @return 是否支持
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T extends Attribute> T[] getSupportedValues(final Class<T> attrClass) {
|
||||
return (T[]) supportedValuesCache.computeIfAbsent(attrClass, k ->
|
||||
printer.getSupportedAttributeValues(k, null, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支持某个属性值
|
||||
*
|
||||
* @param value 属性值
|
||||
* @return 是否支持
|
||||
*/
|
||||
private boolean supportsValue(final Attribute value) {
|
||||
final Object vals = printer.getSupportedAttributeValues(
|
||||
value.getCategory(), null, null);
|
||||
if (vals instanceof final Attribute[] arr) {
|
||||
return Arrays.asList(arr).contains(value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
118
hutool-swing/src/main/java/cn/hutool/v7/swing/PrintUtil.java
Normal file
118
hutool-swing/src/main/java/cn/hutool/v7/swing/PrintUtil.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package cn.hutool.v7.swing;
|
||||
|
||||
import cn.hutool.v7.core.text.StrUtil;
|
||||
|
||||
import javax.print.PrintService;
|
||||
import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.standard.*;
|
||||
import java.awt.print.Printable;
|
||||
import java.awt.print.PrinterException;
|
||||
import java.awt.print.PrinterJob;
|
||||
|
||||
/**
|
||||
* 打印机工具类
|
||||
*
|
||||
* @author Looly
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public class PrintUtil {
|
||||
|
||||
/**
|
||||
* 获取所有可用的打印机
|
||||
*
|
||||
* @return 打印机数组
|
||||
*/
|
||||
public static PrintService[] getPrinters() {
|
||||
return PrinterJob.lookupPrintServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认打印机
|
||||
*
|
||||
* @return 默认打印机
|
||||
*/
|
||||
public static PrintService getDefaultPrinter() {
|
||||
return PrinterJob.getPrinterJob().getPrintService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名称获取打印机
|
||||
*
|
||||
* @param printerName 打印机名称
|
||||
* @return 对应的打印机,未找到返回null
|
||||
*/
|
||||
public static PrintService getPrinter(String printerName) {
|
||||
PrintService[] printers = getPrinters();
|
||||
for (PrintService printer : printers) {
|
||||
if (printer.getName().equals(printerName)) {
|
||||
return printer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查打印机是否可用
|
||||
*
|
||||
* @param printer 打印机
|
||||
* @return 是否可用
|
||||
*/
|
||||
public static boolean isPrinterAvailable(PrintService printer) {
|
||||
try {
|
||||
PrinterJob job = PrinterJob.getPrinterJob();
|
||||
job.setPrintService(printer);
|
||||
return true;
|
||||
} catch (PrinterException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印内容(使用默认打印机)
|
||||
*
|
||||
* @param printable 可打印内容
|
||||
*/
|
||||
public static void print(Printable printable) {
|
||||
print(printable, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印内容
|
||||
*
|
||||
* @param printable 可打印内容
|
||||
* @param printerName 打印机名称(可选)
|
||||
* @param attributes 打印属性(可选)
|
||||
*/
|
||||
public static void print(Printable printable, String printerName, PrintRequestAttributeSet attributes) {
|
||||
try {
|
||||
PrinterJob job = PrinterJob.getPrinterJob();
|
||||
|
||||
if (StrUtil.isNotEmpty(printerName)) {
|
||||
PrintService printer = getPrinter(printerName);
|
||||
if (printer != null) {
|
||||
job.setPrintService(printer);
|
||||
}
|
||||
}
|
||||
|
||||
if (attributes == null) {
|
||||
attributes = new HashPrintRequestAttributeSet();
|
||||
// 打印纸张大小
|
||||
attributes.add(MediaSizeName.ISO_A4);
|
||||
// 打印方向
|
||||
attributes.add(OrientationRequested.PORTRAIT);
|
||||
// 打印质量
|
||||
attributes.add(PrintQuality.NORMAL);
|
||||
// 打印颜色
|
||||
attributes.add(Chromaticity.COLOR);
|
||||
// 打印份数
|
||||
attributes.add(new Copies(1));
|
||||
}
|
||||
|
||||
job.setPrintable(printable);
|
||||
job.print(attributes);
|
||||
} catch (PrinterException e) {
|
||||
throw new SwingException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2025 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hutool.v7.swing;
|
||||
|
||||
import cn.hutool.v7.core.exception.HutoolException;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
/**
|
||||
* Swing异常
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class SwingException extends HutoolException {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param e 异常
|
||||
*/
|
||||
public SwingException(final Throwable e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param message 消息
|
||||
*/
|
||||
public SwingException(final String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param messageTemplate 消息模板
|
||||
* @param params 参数
|
||||
*/
|
||||
public SwingException(final String messageTemplate, final Object... params) {
|
||||
super(messageTemplate, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param message 消息
|
||||
* @param cause 被包装的子异常
|
||||
*/
|
||||
public SwingException(final String message, final Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param message 消息
|
||||
* @param cause 被包装的子异常
|
||||
* @param enableSuppression 是否启用抑制
|
||||
* @param writableStackTrace 堆栈跟踪是否应该是可写的
|
||||
*/
|
||||
public SwingException(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param cause 被包装的子异常
|
||||
* @param messageTemplate 消息模板
|
||||
* @param params 参数
|
||||
*/
|
||||
public SwingException(final Throwable cause, final String messageTemplate, final Object... params) {
|
||||
super(cause, messageTemplate, params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Hutool Team.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hutool.v7.swing;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.print.PrintService;
|
||||
import javax.print.attribute.Attribute;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.standard.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
|
||||
class PrintAttributeBuilderTest {
|
||||
private PrintService testPrinter;
|
||||
private Set<Class<? extends Attribute>> supportedAttributes;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
supportedAttributes = new HashSet<>();
|
||||
testPrinter = PrintUtil.getDefaultPrinter();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testConstructorWithNullPrinter() {
|
||||
assertThrows(NullPointerException.class, () -> new PrintAttributeBuilder(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopies() {
|
||||
// 测试份数设置
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.copies(3);
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
final Copies copies = (Copies) attributes.get(Copies.class);
|
||||
assertNotNull(copies);
|
||||
assertEquals(3, copies.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCopiesWithInvalidValue() {
|
||||
// 测试无效份数(小于1)
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.copies(0);
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
final Copies copies = (Copies) attributes.get(Copies.class);
|
||||
assertNotNull(copies);
|
||||
assertEquals(1, copies.getValue()); // 应该自动修正为1
|
||||
}
|
||||
|
||||
@Test
|
||||
void testJobName() {
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.jobName("Test Job");
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
final JobName jobName = (JobName) attributes.get(JobName.class);
|
||||
assertNotNull(jobName);
|
||||
assertEquals("Test Job", jobName.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testA4PaperWhenNotSupported() {
|
||||
// 确保不支持MediaSizeName
|
||||
supportedAttributes.clear();
|
||||
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.a4Paper();
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
assertNull(attributes.get(MediaSizeName.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLandscapeWhenSupported() {
|
||||
supportedAttributes.add(OrientationRequested.class);
|
||||
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.landscape();
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
assertEquals(OrientationRequested.LANDSCAPE, attributes.get(OrientationRequested.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMonochromeWhenSupported() {
|
||||
supportedAttributes.add(Chromaticity.class);
|
||||
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.monochrome();
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
assertEquals(Chromaticity.MONOCHROME, attributes.get(Chromaticity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPageRange() {
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.pageRange(3, 5);
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
final PageRanges pageRanges = (PageRanges) attributes.get(PageRanges.class);
|
||||
assertNotNull(pageRanges);
|
||||
assertArrayEquals(new int[][]{{3, 5}}, pageRanges.getMembers());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBuildReturnsClone() {
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.copies(2);
|
||||
final PrintRequestAttributeSet attributes1 = builder.build();
|
||||
final PrintRequestAttributeSet attributes2 = builder.build();
|
||||
|
||||
assertNotSame(attributes1, attributes2);
|
||||
assertEquals(attributes1, attributes2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOneSided() {
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.oneSided();
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
final Sides sides = (Sides) attributes.get(Sides.class);
|
||||
assertNotNull(sides);
|
||||
assertEquals(Sides.ONE_SIDED, sides);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testColorWhenSupported() {
|
||||
supportedAttributes.add(Chromaticity.class);
|
||||
|
||||
final PrintAttributeBuilder builder = new PrintAttributeBuilder(testPrinter);
|
||||
builder.color();
|
||||
final PrintRequestAttributeSet attributes = builder.build();
|
||||
|
||||
assertEquals(Chromaticity.COLOR, attributes.get(Chromaticity.class));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user