RadioButton可以交叉而不是子弹吗? - 用于Java的iText 7.1.0

时间:2018-01-18 13:51:49

标签: itext7

有人知道,是否可以有一个十字架(复选框之类)而不是通常的子弹?没找到任何东西。非常感谢!德克

Radio Buttons 为了产生这个结果,我采用了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"));
    }
}

3 个答案:

答案 0 :(得分:1)

这是完全可能的。显然是其中一个常见问题。

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

  

如果要替换外观,则必须替换绘制矩形和十字的流。在IText 7中,我们添加了一些流行的外观,因此您可以在创建以下元素时轻松使用它们:

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

其中checkType可以是:TYPE_CHECK,TYPE_CIRCLE,TYPE_CROSS,TYPE_DIAMOND,TYPE_SQUARE,TYPE_STAR。或者您也可以使用以下方法更改现有元素的外观:

setCheckType(int checkType).

答案 1 :(得分:1)

由于Joris链接的示例并不能立即应用于radiobuttons(看起来它们的外观在默认情况下被硬编码为圆形),我写了一个简单的例子,向您展示如何覆盖该外观在将整个无线电组添加到表单字段之前创建按钮对象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,其中包含十字形而不是圆形的绘图说明。

答案 2 :(得分:0)

无法完全更改单选按钮的子弹。​​

Samuel Huylebroeck的解决方案仅在与Radio Button Group交互时才有效:
点击“荷兰语”后,它看起来像这样:

clicking on "Dutch"

但是在离开Radio Button Group之后,例如通过点击页面的另一部分,它看起来像这样:

leaving Radio Group

这是单选按钮的标准外观,不能更改。这很可惜,知道为什么会这样,这将是非常有趣的。

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

Print Preview