是否可以使用带有十字而不是子弹的 RadioButton? - Java 的 iText 7.1.0

Is RadioButton with cross instead of bullet possible? - iText 7.1.0 for Java

有谁知道,是否可以用叉号(复选框之类的)代替通常的项目符号?没找到任何东西。非常感谢!德克

为了产生这个结果,我采用了一个 iText 示例

package jumpstart;

import com.itextpdf.forms.PdfAcroForm;
import com.itextpdf.forms.fields.PdfButtonFormField;
import com.itextpdf.forms.fields.PdfFormField;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.property.TextAlignment;

import java.awt.Desktop;
import java.io.File;

public class Problem8 {
    public static void main(String[] args) throws Exception {
        PdfWriter writer = new PdfWriter("problem8.pdf");
        PdfDocument pdf = new PdfDocument(writer);
        Document doc = new Document(pdf);
        PdfFont font = PdfFontFactory.createFont("src/main/resources/fonts/arialuni.ttf", PdfEncodings.IDENTITY_H, true);
        PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
        String[] languages = { "Dutch", "English", "French" };
        Rectangle rect;
        Paragraph para;
        PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdf, "Language", "");
        pdf.addNewPage();
        for (int i = 1; i <= languages.length; i++) {
            rect = new Rectangle(40, 800 - i * 30, 20, 20);
            para = new Paragraph(languages[i - 1]);
            para.setFont(font);
            para.setFontSize(18);
            PdfFormField.createRadioButton(pdf, rect, radioGroup, languages[i - 1]);
            doc.showTextAligned(para, 70, 800 - i * 30, TextAlignment.LEFT);
        }
        form.addField(radioGroup);
        doc.close();
        Desktop.getDesktop().open(new File("problem8.pdf"));
    }
}

完全有可能。显然还有一个常见问题解答。

https://developers.itextpdf.com/de/node/3095

If you want to replace the appearance, then you have to replace the stream that draws the rectangle and the cross. In IText 7 we added some popular appearances, so you can easily use them while creating elements like:

createCheckBox(PdfDocument doc, Rectangle rect, String name, String value, int checkType)

Where checkType can be: TYPE_CHECK, TYPE_CIRCLE, TYPE_CROSS, TYPE_DIAMOND, TYPE_SQUARE, TYPE_STAR. Or you can also change the appearance of existing element using:

setCheckType(int checkType).

由于 Joris 链接的示例不会立即应用于单选按钮(看起来它们的外观默认情况下被硬编码为圆形),我写了一个简单的示例来向您展示如何覆盖该外观在将整个无线电组添加到表单字段之前创建按钮对象 bu 之后:

public void createPdf(String dest) throws IOException, java.io.IOException{
    float width = 20;
    float height = 20;
    List<PdfFormField> radiobuttons = new ArrayList<>();
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    Document doc = new Document(pdf);
    //PdfFont font = PdfFontFactory.createFont("src/main/resources/fonts/arialuni.ttf", PdfEncodings.IDENTITY_H, true);
    PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
    String[] languages = { "Dutch", "English", "French" };
    Rectangle rect;
    Paragraph para;
    PdfButtonFormField radioGroup = PdfFormField.createRadioGroup(pdf, "Language", "");
    pdf.addNewPage();
    for (int i = 1; i <= languages.length; i++) {
        rect = new Rectangle(40, 800 - i * 30, width, height);
        para = new Paragraph(languages[i - 1]);
        //para.setFont(font);
        para.setFontSize(18);
        PdfFormField radioButton = PdfFormField.createRadioButton(pdf, rect, radioGroup, languages[i - 1]);
        createAndSetCircleGraphicForOn(radioButton,pdf,width,height, languages[i-1]);
        radiobuttons.add(radioButton);
        doc.showTextAligned(para, 70, 800 - i * 30, TextAlignment.LEFT);
    }
    form.addField(radioGroup);
    doc.close();
}

private static void createAndSetCircleGraphicForOn(PdfFormField radiobutton, PdfDocument pdfDoc, float width, float height, String value){
    PdfStream streamOn = (PdfStream) new PdfStream().makeIndirect(pdfDoc);
    PdfCanvas canvasOn = new PdfCanvas(streamOn, new PdfResources(), pdfDoc);
    Rectangle rect = new Rectangle(0, 0, width, height);
    PdfFormXObject xObjectOn = new PdfFormXObject(rect);

    drawRadioFieldOnWithCross(canvasOn, ColorConstants.BLACK,1f, width, height, true);

    PdfStream streamOff = (PdfStream) new PdfStream().makeIndirect(pdfDoc);

    PdfWidgetAnnotation widget = radiobutton.getWidgets().get(0);

    xObjectOn.getPdfObject().getOutputStream().writeBytes(streamOn.getBytes());
    widget.setNormalAppearance(new PdfDictionary());
    widget.getNormalAppearanceObject().put(new PdfName(value), xObjectOn.getPdfObject());
}

private static void drawRadioFieldOnWithCross(PdfCanvas canvas,Color strokeColor, float strokeWidth, float width, float height, boolean on) {
    canvas.saveState();
    if (on) {
        canvas.
                setStrokeColor(strokeColor)
                .setLineWidth(strokeWidth)
                //bottom left to top right
                .moveTo(0,0)
                .lineTo(width,height)
                .stroke()
                //Top left to bottom right
                .moveTo(0,height)
                .lineTo(width,0)
                .stroke();
    }
    canvas.restoreState();
}

它的工作原理是将值状态的外观流替换为 PdfStream包含十字而不是圆形的绘图指令。

无法完全更改单选按钮的项目符号。

Samuel Huylebroeck 的解决方案仅在与Radio Button Group:
然后点击"Dutch"之后是这样的:

但是离开单选按钮组后,例如通过单击页面的另一部分,它看起来像这样:

这是无法更改的单选按钮的标准外观。真可惜,知道为什么会这样会很有趣。

令人困惑的是打印预览再次显示十字: