¿Alguien sabe, si es posible tener una cruz (casilla de verificación como) en lugar de la bala habitual? No encontré nada. ¡Muchas gracias! Puñal

Botones de radio Para producir este resultado, adopté una muestra de 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"));
    }
}
1
Dirk Kampfmeier 18 ene. 2018 a las 16:51

3 respuestas

La mejor respuesta

No es posible cambiar completamente la viñeta de un botón de radio.

La solución de Samuel Huylebroeck funciona solo cuando interactúa con el grupo de botones de radio:
Luego se ve así después de hacer clic en "holandés":

clicking on "Dutch"

Pero después de abandonar el Grupo de botones de radio, por ejemplo, al hacer clic en otra parte de la página, se ve así:

leaving Radio Group

Esta es la apariencia estándar de un botón de radio que no se puede modificar. Es una pena y sería muy interesante saber por qué es así.

Es confuso que la vista previa de la impresión muestre la cruz nuevamente:

Print Preview

0
Dirk Kampfmeier 20 ene. 2018 a las 12:25

Eso es perfectamente posible. Y una de las preguntas frecuentes aparentemente.

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

Si desea reemplazar la apariencia, debe reemplazar la secuencia que dibuja el rectángulo y la cruz. En IText 7 agregamos algunas apariencias populares, para que pueda usarlas fácilmente mientras crea elementos como:

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

Donde checkType puede ser: TYPE_CHECK, TYPE_CIRCLE, TYPE_CROSS, TYPE_DIAMOND, TYPE_SQUARE, TYPE_STAR. O también puede cambiar la apariencia del elemento existente usando:

setCheckType(int checkType).
1
Joris Schellekens 18 ene. 2018 a las 14:16

Dado que el ejemplo vinculado por Joris no se aplica inmediatamente a los botones de radio (parece que su apariencia está codificada de forma predeterminada para ser un círculo por defecto), escribí un ejemplo simple que muestra cómo anular esa apariencia después de crear el botón. object bu antes de agregar todo el grupo de radio a los campos del formulario:

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();
}

Funciona reemplazando la secuencia de apariencia para el estado de valor con un PdfStream que contiene las instrucciones de dibujo para una cruz en lugar de un círculo.

1
Samuel Huylebroeck 19 ene. 2018 a las 13:08
48322943