I use iTextSharp v5.5.6
I'm creating a large table.
To be consistent in my layout I want to use the DefaultCell class to set some default settings like font, padding and alignment.
I'm not doing something correct because the settings are not applied to my cells.
Here's some code:
var table = new PdfPTable(2)
{ KeepTogether = true, TotalWidth = printWidth, LockedWidth = true,
HorizontalAlignment = 0, SpacingBefore = 0, SpacingAfter = 15f };
// Set default values:
table.DefaultCell.Colspan = 1;
table.DefaultCell.HorizontalAlignment = Element.ALIGN_LEFT;
table.DefaultCell.Padding = 5f;
table.DefaultCell.PaddingLeft = 5f;
table.DefaultCell.PaddingBottom = 5f;
table.DefaultCell.VerticalAlignment = Element.ALIGN_BOTTOM;
table.DefaultCell.BorderWidthBottom = 0f;
table.DefaultCell.Phrase = new Phrase { Font = Blue11BoldFont };
table.DefaultCell.Border = Rectangle.NO_BORDER;
table.AddCell(new PdfPCell(new Phrase("Foo"))
{ HorizontalAlignment = Element.ALIGN_CENTER, MinimumHeight = 20f });
table.AddCell(new PdfPCell(new Phrase("Bar", Black10BoldFont))
{ Colspan = 4, HorizontalAlignment = Element.ALIGN_CENTER });
I would have expected my first cell would use my blue font and padding is applied.
But nothing is applied. In fact when I remove the DefaultCell lines I get the same result.
I've been searching for hours now and most samples I've found use something similar.
Any suggestion is much appreaciated.
You are creating PdfPCell objects yourself. In that case, the default cell is always ignored.
See What is the PdfPTable.DefaultCell property used for?
When creating a PdfPTable, you add cells.
One way is to create a PdfPCell object and to add that cell with the addCell() method. In this case, you are responsible to define the properties of each individual cell.
Another way is to use a short-cut: you don't create a PdfPCell, but you add a String or a Phrase to the table with the addCell() method. In this case, a PdfPCell is created internally using default properties. You can change the default properties by changing the properties of the default cell. The default cell is obtained using the getDefaultCell() method.
This is not a bug, this is by design. You are misinterpreting the meaning of the concept of the "default cell". Note that this concept was explained in the free ebook The Best iText Questions on StackOverflow.
If you want to be consistent in your layout, the best way to do this, is by creating your own createCell() method that creates a PdfPCell to which you apply all the properties for which you were using the default cell.
Related
I am trying to implement my first unity editor code to make a custom array property drawer with indented named entries and indented and dynamicaly resized value fields.
I am using the following simple git solution as base for my code, which allows to set the labels of an array in the inspector : HERE
replacing the example shown in the gitHub solution, I am working with this enum as my array element name container:
[System.Serializable]
public enum HealthNames
{
General,
Head,
Body,
RightArm,
LeftArm,
Rightleg,
leftLeg,
}
and sets it up on a array in a monobehaviour class :
[ LabeledArray( typeof( HealthNames ) ) ]
public int[] m_aHealth = new int[ Enum.GetNames( typeof( HealthNames ) ).Length ];
I have added EditorGUI.indentLevel++; and EditorGUI.indentLevel--; at the start and end of the try statement to indent the label of the array elements, making them stand out from the size property.
Going from there, I have searched ways to add an indent on the elements' value fields or remove it from the size property's value field. but have found no answer using EditorGUI
I also looked to be able to resize all value fields dynamicaly, but there again, no answer came using EditorGUI only. there is no way to use EditorStyle.AnyField.WordWrap = true; on a propertyfield. Passing the PropertyField to an IntField, using a EditorStyles.NumberField and setting having its wrodwrapping set to true beforehand has no effect.
I also have found a small number of EditorGUILayout from a few years ago, but which do not work since the solution is built from the ground with EditorGUI
In hope of your enlightment on the matter
If I understand you correctly you want the labels and the value fields indented.
I think it could be done like e.g.
private const int INDENT = 15;
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(rect, label, property);
var fieldsRect = new Rect(rect.x + INDENT, rect.y, rect.width - INDENT, rect.height);
try
{
var path = property.propertyPath;
int pos = int.Parse(path.Split('[').LastOrDefault().TrimEnd(']'));
EditorGUI.PropertyField(fieldRect, property, new GUIContent(ObjectNames.NicifyVariableName(((LabeledArrayAttribute)attribute).names[pos])), true);
}
catch
{
EditorGUI.PropertyField(fieldRect, property, label, true);
}
EditorGUI.EndProperty();
}
I'm using iTextSharp 5.5.13 and when i try to generate the PDF with Hebrew it comes out empty.
this is my code: I'm i doing something wrong?
public byte[] GenerateIvhunPdf(FinalIvhunSolution ivhun)
{
byte[] pdfBytes;
using (var mem = new MemoryStream())
{
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(document, mem);
writer.PageEvent = new MyHeaderNFooter();
document.Open();
var font = new
Font(BaseFont.CreateFont("C:\\Downloads\\fonts\\Rubik-Light.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 14);
Paragraph p = new Paragraph("פסקת פתיחה")
{
Alignment = Element.ALIGN_RIGHT
};
PdfPTable table = new PdfPTable(2)
{
RunDirection = PdfWriter.RUN_DIRECTION_RTL
};
PdfPCell cell = new PdfPCell(new Phrase("מזהה", font));
cell.BackgroundColor = BaseColor.BLACK;
table.AddCell(cell);
document.Add(p);
document.Add(table);
document.Close();
pdfBytes = mem.ToArray();
}
return pdfBytes;
}
The PDF comes out blank
I changed a few details of your code, and now I get this:
My changes:
Embedding the font
As I don't have Rubik installed on my system, I have to embed the font into the PDF to have a chance to see anything. Thus, I replaced BaseFont.NOT_EMBEDDED by BaseFont.EMBEDDED when creating the var font:
var font = new Font(BaseFont.CreateFont("Rubik-Light.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 14);
Making the Paragraph kind of work
You create the Paragraph p without specifying a font. Thus, a default font with default encoding is used. The default encoding is WinAnsiEncoding which is Latin1-like, so no Hebrew characters can be represented. I added your Rubik font instance to the Paragraph p creation:
Paragraph p = new Paragraph("פסקת פתיחה", font)
{
Alignment = Element.ALIGN_RIGHT
};
Et voilà, the writing appears.
iText developers often have communicated that in iText 5.x and earlier right-to-left scripts are only supported properly in certain contexts, e.g. in tables, but not in others like paragraphs immediately added to the document. As your Paragraph p is added immediately to the Document document, its letters appear in the wrong order in the output.
Making the PdfPTable work
You defined the PdfPTable table to have two columns (new PdfPTable(2)) but then you added only one cell. Thus, table contains not even a single complete row. iText, therefore, draws nothing when it is added to the document.
I changed the definition of table to have a single column only:
PdfPTable table = new PdfPTable(1)
{
RunDirection = PdfWriter.RUN_DIRECTION_RTL
};
Furthermore, I commented out the line setting the cell background to black because usually it is difficult to read black on black:
PdfPCell cell = new PdfPCell(new Phrase("מזהה", font));
//cell.BackgroundColor = BaseColor.BLACK;
table.AddCell(cell);
And again the writing appears.
Properly downloading the font
Another possible obstacle is that when downloading the font from the URL you gave — https://fonts.google.com/selection?selection.family=Rubik — one can see in the customization tab of the selection drawer that by default only Latin characters are included in the download, in particular not Hebrew ones:
I tested with a font file I downloaded with all language options enabled:
I am trying to create table using Javafx, i need for some columns cells to be selectable but not editable,
if i used : textColumn.setEditable(true);
but it will make it editable
if i used : textColumn.setEditable(false); it will be neither selectable nor editabe
how can i make column selectable but not editable ?
Here it is my code sample
TableColumn<Tuple, String> textColumn= new TableColumn<>();
textColumn.setText(column.getName());
textColumn.setMinWidth(column.getWidth());
textColumn.setEditable(true);
There is no default copying mechanism for TableView (columns could contain arbitraty value types that could require costom treatment when copying to the clipboard). You should implement the copying mechanism yourself, if needed.
Example:
tableView.setOnKeyReleased(evt -> {
if (evt.isControlDown() && evt.getCode() == KeyCode.C) {
List<TablePosition> selectedCells = table.getSelectionModel().getSelectedCells();
if (!selectedCells.isEmpty()) {
TablePosition selectedCell = selectedCells.get(0);
if (selectedCell.getTableColumn() == textColumn) {
String value = textColumn.getCellData(selectedCell.getRow());
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putString(value);
clipboard.setContent(content);
}
}
}
});
This needs to be done in addition to doing
tableView.getSelectionModel().setCellSelectionEnabled(true);
It assumes you're using to the standard cell type.
Because I use Comboboxes that may contain text entries of very long size,
which leads to the combobox increasing its width far beyond reasonable size,
I am trying to give a maximum width to the combobox.
If I am doing this like this:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
render.property_width_chars() = 10;
render.property_ellipsize() = Pango::ELLIPSIZE_END;
pack_start(render, true);
}
};
The result will be an empty cell of the desired width, which seems logical since I did not specify which column to show. But how can I do this with that attempt? Using pack_start will just bypass the renderer...
Another approach is this one:
class MyCombo : public Gtk::ComboBox {
private:
CellRendererText render;
public:
MyCombo() {
pack_start(render, true);
set_cell_data_func(render, sigc::mem_fun(*this, &MyCombo::render_iter));
}
void render_iter(const TreeModel::const_iterator& iter) {
Glib::ustring data = get_string_from_iter(iter);
int desired_width_chars = 10; //for example
render.property_text() = ellipsize_string(data, desired_width_chars);
}
};
Using that approach, it works, but the text in the popup (what opens up when u click the combobox) is also shortened which is not what I want (obviously the user should be able to read the whole string and I dont care about the popup widht.)
Can you please help me with this? I would be happy for any advice/alternative solutions.
Regards tagelicht
NOTE: set_wrap_width is a function that wraps the total number of entries in the combo box over a number of columns specified; it does not answer the question.
Using set_wrap_width(1) | Using set_wrap_width(5)
Following Noup's answer as a guide I managed to get the below code; which directly answers the question and its requirements (C++/Gtkmm).
// Get the first cell renderer of the ComboBox.
auto v_cellRenderer = (Gtk::CellRendererText*)v_comboBox.get_first_cell();
// Probably obsolete; Sets character width to 1.
v_cellRenderer->property_width_chars() = 1;
// Sets the ellipses ("...") to be at the end, where text overflows.
// See Pango::ELLIPSIZE enum for other values.
v_cellRenderer->property_ellipsize() = Pango::ELLIPSIZE_END;
// Sets the size of the box, change this to suit your needs.
// -1 sets it to automatic scaling: (width, height).
v_cellRenderer->set_fixed_size(200, -1);
Result (image):
Result of code
BE AWARE: Depending on where you perform the above code; either all the cells will be the same size, or just the box itself (intended).
From experimenting, I've found:
In the parent object constructor: All cell sizes are the same.
In a separate function: Only the first cell (the box) is affected.
I'd recommend you put the code in a function that's connected to the comboBox's changed signal, such as:
v_comboBox.signal_changed().connect(sigc::mem_fun(*this, &YourClass::comboBox_changedFunction));
This may be what you are looking for:
cell_renderer_text.set_wrap_width(10)
This is for Python, but you get the idea :-)
Unfortunately, the documentation is scarce. I found this by poking around in Anjuta/Glade.
Edit:
the docs are here. They are not overly helpful, but they do exist.
As an alternative, the following works for me without having to set wrap_width nor to subclass ComboBox (in Gtk#):
ComboBoxText cb = new ComboBoxText();
cb.Hexpand = true; //If there's available space, we use it
CellRendererText renderer = (cb.Cells[0] as CellRendererText); //Get the ComboBoxText only renderer
renderer.WidthChars = 20; //Always show at least 20 chars
renderer.Ellipsize = Pango.EllipsizeMode.End;
Note: I'm using Expand to use space if it's available. If you just want to keep the combo box on a fixed width, just remove that bit.
There is a List in a LWUIT application. I want to make odd rows and even rows to be of different colors. How to achieve that ?
You can set two differents UIIDs to the rows. Setting this UIID you can modify selectively the colors of your rows.
EDIT
Ok this will be more difficult.
You need to make a Render and set it in your List with List.setRender(Render r).
The ´Render´ class will extend from ListCellRender. In this class you can set UIID to the Render, setting its Selected or Unselected styles.
See this example. #Shai Almog could have more info for your problem.
http://www.lwuit.com/2008/07/lwuit-list-renderer-by-chen-fishbein.html
What you need is the Generic List Cell Renderer, you will probably have to create the styles in code, or set the UIID from the resource editor.
List list = new List(createGenericListCellRendererModelData());
list.setRenderer(new GenericListCellRenderer(createGenericRendererContainer(), createGenericRendererContainer()));
private Container createGenericRendererContainer() {
Container c = new Container(new BorderLayout());
c.setUIID("ListRenderer");
Label name = new Label();
name.setFocusable(true);
name.setName("Name");
c.addComponent(BorderLayout.CENTER, name);
Label surname = new Label();
surname.setFocusable(true);
surname.setName("Surname");
c.addComponent(BorderLayout.SOUTH, surname);
CheckBox selected = new CheckBox();
selected.setName("Selected");
selected.setFocusable(true);
c.addComponent(BorderLayout.WEST, selected);
return c;
}
private Hashtable[] createGenericListCellRendererModelData() {
Hashtable[] data = new Hashtable[5];
data[0] = new Hashtable();
data[0].put("Name", "Shai");
data[0].put("Surname", "Almog");
data[0].put("Selected", Boolean.TRUE);
data[1] = new Hashtable();
data[1].put("Name", "Chen");
data[1].put("Surname", "Fishbein");
data[1].put("Selected", Boolean.TRUE);
data[2] = new Hashtable();
data[2].put("Name", "Ofir");
data[2].put("Surname", "Leitner");
data[3] = new Hashtable();
data[3].put("Name", "Yaniv");
data[3].put("Surname", "Vakarat");
data[4] = new Hashtable();
data[4].put("Name", "Meirav");
data[4].put("Surname", "Nachmanovitch");
return data;
}
Full details here : http://lwuit.blogspot.com/2011/03/list-rendering-easy-way-generic-list.html (code gotten from this link).