Can't set cell width using docx4j - java

How to set width for cell? I tried trough cell properties, but it does not work
private void addTableCell(Tr tableRow, String content, boolean setWidth, int width) {
Tc tableCell = factory.createTc();
if (setWidth) {
setCellWidth(tableCell, width);
}
tableCell.getContent().add(
wordMLPackage.getMainDocumentPart().
createParagraphOfText(content));
tableRow.getContent().add(tableCell);
}
private void setCellWidth(Tc tableCell, int width) {
TcPr tableCellProperties = new TcPr();
TblWidth tableWidth = new TblWidth();
tableWidth.setW(BigInteger.valueOf(width));
tableCellProperties.setTcW(tableWidth);
tableCell.setTcPr(tableCellProperties);
}

You should also set w:tbl/w:tblGrid; see further ecma376/WordML/Tables
The easiest way to set things appropriately is to make a table to your liking in Word, then generate corresponding code from that using the docx4j webapp, or the Docx4jHelper Word AddIn.
For more on w:tcW, see the spec.

It's possible you need to set the width type for the cell. Try adding
tableWidth.setType("dxa");
before calling setTcW() in your setCellWidth function.

Related

Im trying to set column width on excel 2010 using setcolumnwidth

I'm trying to set the colunm width with setColumnWidth(rowindex, width) using POI,problem is the width is in double and the function above only accept Int
I tried using autosizecolumn but its still living underpopulated space in the column, problem i think is the font mismatch between excel and java
code
RowTotal = NewSheet.createRow(0);
cell1 = RowTotal.createCell(0);
cell1.setCellValue("Row Name/Label");
cell1 = RowTotal.createCell(1);
cell1.setCellValue("Sum of premium payable");
cell1 = RowTotal.createCell(2);
cell1.setCellValue("Sum of arrears payable");
NewSheet.setColumnWidth(0, 3755.84);
NewSheet.setColumnWidth(1, 5519.68);;
NewSheet.setColumnWidth(2, 5207.36);
You cannot pass double value to setColumnWidth as well as to autosizecolumn because both the methods of Apache POI accepts int value as parameters.
Methods of Apache POI:
1. autoSizeColumn(int column)
Adjusts the column width to fit the contents.
2. setColumnWidth(int columnIndex, int width)
Set the width (in units of 1/256th of a character width)
you can refer to https://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFSheet.html
for more details.
Use:
NewSheet.getColumnHelper().setColWidth(0, 3755.84);
NewSheet.getColumnHelper().setCustomWidth(0, true);
I'm not sure if the second line is necessary but if you manually change the width of a column in excel, it will automatically set CustomWidth = true. So I just add it to be safe.

jTable not coloring row correctly

i have a problem, basically my program looks like this:
the thing is, it works, it is supposed to color the rows that have "N" in green, but the first time it loads the values, as you can see, the first row have bits of white, but for some reason if i click the list it fixes the issue, i need the rows to be colored properly without the user needing to click on the list to fix the issue, this is my Render code:
public class Render extends JTable {
#Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex,
int columnIndex){
Component componente = super.prepareRenderer(renderer, rowIndex, columnIndex);
String val = getValueAt(rowIndex, columnIndex).toString();
if(val.equals("N")){
componente.setBackground(Color.GREEN);
}
return componente;
}
}
I figured i could use Repaint(); in the MouseMoved event in the JTable, but i think is not a proper way to fix it... Any help is appreciated, cheers!
Start by changing
String val = getValueAt(rowIndex, columnIndex).toString();
to
String val = getValueAt(rowIndex, 3).toString();
This will ensure that no matter what column the cell represents, you are checking the appropriate columns value - this is why the leading cells are white
You should also consider providing a default color for when the column values doesn't match
if (val.equals("N")) {
componente.setBackground(Color.GREEN);
} else {
componente.setBackground(getBackground());
}

How to get the currently selected cell's indices in JTable immediately after it is highlighted?

I'm building a spread sheet application. But this is not a question like using table.getSelectedColumn() and table.getSelectedRow() to find the selected cell in a JTable.
In Microsoft Excel, when we navigate through cells using arrow keys, the content in the cells are displayed in the Formula Bar immediately after highlighting the cell. Here, the most important thing is, when a cell is highlighted by the selection as above, the value inside the cell is displayed at the sametime. So my question is, how can we do the same in JTable?
I have tried to do something similar using keyEvent listener, but the problem with that is, when a key event is generated, the next cell is being highlighted but the indices of the previous(which was previously highlighted) is being returned in the getSelectedRow() and getSelectedColumn() methods.
Also i tried the ListSelectionListener. but the same fault exists.
If there's any way to get the selected cell's indices immediately after the new cell is highlighted when navigated using arrow keys, that will work. Also an event should be generated since I want to update the formula bar as in Excel. Can someone help me with this?
Thanks in advance!
You can use this simple trick!
Only have to make two excess jTextfields. (can set to be invisible at the run time)
Try to get an idea from below code segment.
private int r;
private int c;
private String buffer;
private void jTextField1KeyTyped(java.awt.event.KeyEvent evt) {
jTextField2.requestFocus();
buffer = jTextField1.getText();
jTable1.getModel().setValueAt(jTextField1.getText(), r, c);
}
private void jTable1KeyTyped(java.awt.event.KeyEvent evt) {
r = jTable1.getSelectedRow();
c = jTable1.getSelectedColumn();
jTable1.putClientProperty("terminateEditOnFocusLost", true);
jTextField1.requestFocus();
}
private void jTextField1FocusGained(java.awt.event.FocusEvent evt) {
buffer = (String)jTable1.getModel().getValueAt(r, c);
jTextField1.setText(buffer);
jLabel1.setText(buffer);
}
private void jTextField2FocusGained(java.awt.event.FocusEvent evt) {
buffer = jTextField1.getText();
jTable1.getModel().setValueAt(buffer, r, c);
jTextField1.requestFocus();
}

Given two label fields inside an HorizontalFieldManager, how should I do to display the full text from second label without wrapping it?

I have an HorizontalFieldManager with two labels inside.
The left label shows a description, and the right one shows
a money amount.
For me, it's more important to show the full text of the
second label. Problem is that if the first label is too long,
the second label will be wrapped. I want to avoid that, so
text from second label always is displayed. I also need to avoid
the wrapping over first label in that case, so text from that label
is trimmed and filled with dots.
This is how the HorizontalFieldManager looks:
And this is what I need to get:
How should I do that?
Thanks in advance!
If you create your LabelField with the LabelField.ELLIPSIS flag, it will truncate the field with . characters. I would recommend that you use a custom Manager subclass (instead of HorizontalFieldManager) to decide what the proper width of your two LabelFields should be. You can do this by asking what the proper width is of the dollar amount, given the current font.
Try this example:
public class LabelAlignScreen extends MainScreen {
private LabelField description;
private LabelField balance;
private static final int MARGIN = 8; // used for x and y
public LabelAlignScreen() {
super(MainScreen.VERTICAL_SCROLL | MainScreen.VERTICAL_SCROLLBAR);
Manager row = new RowManager(Manager.USE_ALL_WIDTH);
description = new LabelField("This is a very looooooooooong description",
LabelField.ELLIPSIS);
row.add(description);
balance = new LabelField("1,500,000,000 USD");
row.add(balance);
add(row);
}
private class RowManager extends Manager {
public RowManager(long flags) {
super(flags);
}
protected void sublayout(int width, int height) {
// first, determine how much space the balance field needs
int balanceWidth = balance.getFont().getAdvance(balance.getText());
// description field gets leftover width,
// minus a margin at left, center and right
int descriptionWidth = width - balanceWidth - 3 * MARGIN;
setPositionChild(description, MARGIN, MARGIN);
layoutChild(description, descriptionWidth, description.getPreferredHeight());
setPositionChild(balance, MARGIN + descriptionWidth + MARGIN, MARGIN);
layoutChild(balance, balanceWidth, balance.getPreferredHeight());
setExtent(width, getPreferredHeight());
}
public int getPreferredHeight() {
return Math.max(balance.getPreferredHeight(), description.getPreferredHeight()) + 2 * MARGIN;
}
public int getPreferredWidth() {
return Display.getWidth();
}
}
}
Note: you didn't specify whether the dollar/balance field should be a fixed width, or always just barely enough to fit the text. I assumed that it should just barely fit the text, as I think that makes for a better layout in most cases. Also, my code above uses a hardcoded MARGIN value for the space around all the fields. You can adjust that if you like.
Results
See that example :
class Test {
public String StringShorter(String field, int maxsize) {
//create a function that process the String you want to put in your field
StringBuilder strb=new StringBuilder();
// lets say you want your field to not more than 10 characters
if(field.length()>=maxsize) {
strb.append(field.substring(0,maxsize));
strb.append("...");
}
return strb.toString();
}
public static void main(String[] args) {
Test sl=new Test();
System.out.println(sl.StringShorter("sdadasfdfsdfsdfsdfdsffdfs", 10));
// define the maximum characters here it is defined to be maximum 10 characters
}
}
the output would be :
sdadasfdfs...

Java JTable setting Column Width

I have a JTable in which I set the column size as follows:
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);
This works fine, but when the table is maximized, I get empty space to the right of the last column. Is it possible to make the last column resize to the end of the window when resized?
I found AUTO_RESIZE_LAST_COLUMN property in docs but it does not work.
Edit: JTable is in a JScrollPane its prefered size is set.
What happens if you call setMinWidth(400) on the last column instead of setPreferredWidth(400)?
In the JavaDoc for JTable, read the docs for doLayout() very carefully. Here are some choice bits:
When the method is called as a result of the resizing of an enclosing window, the
resizingColumn is null. This means that resizing has taken place "outside" the JTable
and the change - or "delta" - should be distributed to all of the columns regardless of
this JTable's automatic resize mode.
This might be why AUTO_RESIZE_LAST_COLUMN didn't help you.
Note: When a JTable makes adjustments to the widths of the columns it respects their
minimum and maximum values absolutely.
This says that you might want to set Min == Max for all but the last columns, then set Min = Preferred on the last column and either not set Max or set a very large value for Max.
With JTable.AUTO_RESIZE_OFF, the table will not change the size of any of the columns for you, so it will take your preferred setting. If it is your goal to have the columns default to your preferred size, except to have the last column fill the rest of the pane, You have the option of using the JTable.AUTO_RESIZE_LAST_COLUMN autoResizeMode, but it might be most effective when used with TableColumn.setMaxWidth() instead of TableColumn.setPreferredWidth() for all but the last column.
Once you are satisfied that AUTO_RESIZE_LAST_COLUMN does in fact work, you can experiment with a combination of TableColumn.setMaxWidth() and TableColumn.setMinWidth()
JTable.AUTO_RESIZE_LAST_COLUMN is defined as "During all resize operations, apply adjustments to the last column only" which means you have to set the autoresizemode at the end of your code, otherwise setPreferredWidth() won't affect anything!
So in your case this would be the correct way:
table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(400);
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
Use this method
public static void setColumnWidths(JTable table, int... widths) {
TableColumnModel columnModel = table.getColumnModel();
for (int i = 0; i < widths.length; i++) {
if (i < columnModel.getColumnCount()) {
columnModel.getColumn(i).setMaxWidth(widths[i]);
}
else break;
}
}
Or extend the JTable class:
public class Table extends JTable {
public void setColumnWidths(int... widths) {
for (int i = 0; i < widths.length; i++) {
if (i < columnModel.getColumnCount()) {
columnModel.getColumn(i).setMaxWidth(widths[i]);
}
else break;
}
}
}
And then
table.setColumnWidths(30, 150, 100, 100);
Reading the remark of Kleopatra (her 2nd time she suggested to have a look at javax.swing.JXTable, and now I Am sorry I didn't have a look the first time :) )
I suggest you follow the link
I had this solution for the same problem: (but I suggest you follow the link above)
On resize the table, scale the table column widths to the current table total width.
to do this I use a global array of ints for the (relative) column widths):
private int[] columnWidths=null;
I use this function to set the table column widths:
public void setColumnWidths(int[] widths){
int nrCols=table.getModel().getColumnCount();
if(nrCols==0||widths==null){
return;
}
this.columnWidths=widths.clone();
//current width of the table:
int totalWidth=table.getWidth();
int totalWidthRequested=0;
int nrRequestedWidths=columnWidths.length;
int defaultWidth=(int)Math.floor((double)totalWidth/(double)nrCols);
for(int col=0;col<nrCols;col++){
int width = 0;
if(columnWidths.length>col){
width=columnWidths[col];
}
totalWidthRequested+=width;
}
//Note: for the not defined columns: use the defaultWidth
if(nrRequestedWidths<nrCols){
log.fine("Setting column widths: nr of columns do not match column widths requested");
totalWidthRequested+=((nrCols-nrRequestedWidths)*defaultWidth);
}
//calculate the scale for the column width
double factor=(double)totalWidth/(double)totalWidthRequested;
for(int col=0;col<nrCols;col++){
int width = defaultWidth;
if(columnWidths.length>col){
//scale the requested width to the current table width
width=(int)Math.floor(factor*(double)columnWidths[col]);
}
table.getColumnModel().getColumn(col).setPreferredWidth(width);
table.getColumnModel().getColumn(col).setWidth(width);
}
}
When setting the data I call:
setColumnWidths(this.columnWidths);
and on changing I call the ComponentListener set to the parent of the table (in my case the JScrollPane that is the container of my table):
public void componentResized(ComponentEvent componentEvent) {
this.setColumnWidths(this.columnWidths);
}
note that the JTable table is also global:
private JTable table;
And here I set the listener:
scrollPane=new JScrollPane(table);
scrollPane.addComponentListener(this);
This code is worked for me without setAutoResizeModes.
TableColumnModel columnModel = jTable1.getColumnModel();
columnModel.getColumn(1).setPreferredWidth(170);
columnModel.getColumn(1).setMaxWidth(170);
columnModel.getColumn(2).setPreferredWidth(150);
columnModel.getColumn(2).setMaxWidth(150);
columnModel.getColumn(3).setPreferredWidth(40);
columnModel.getColumn(3).setMaxWidth(40);
fireTableStructureChanged();
will default the resize behavior ! If this method is called somewhere in your code AFTER you did set the column resize properties all your settings will be reset. This side effect can happen indirectly. F.e. as a consequence of the linked data model being changed in a way this method is called, after properties are set.
No need for the option, just make the preferred width of the last column the maximum and it will take all the extra space.
table.getColumnModel().getColumn(0).setPreferredWidth(27);
table.getColumnModel().getColumn(1).setPreferredWidth(120);
table.getColumnModel().getColumn(2).setPreferredWidth(100);
table.getColumnModel().getColumn(3).setPreferredWidth(90);
table.getColumnModel().getColumn(4).setPreferredWidth(90);
table.getColumnModel().getColumn(6).setPreferredWidth(120);
table.getColumnModel().getColumn(7).setPreferredWidth(100);
table.getColumnModel().getColumn(8).setPreferredWidth(95);
table.getColumnModel().getColumn(9).setPreferredWidth(40);
table.getColumnModel().getColumn(10).setPreferredWidth(Integer.MAX_INT);
Use this code. It worked for me. I considered for 3 columns. Change the loop value for your code.
TableColumn column = null;
for (int i = 0; i < 3; i++) {
column = table.getColumnModel().getColumn(i);
if (i == 0)
column.setMaxWidth(10);
if (i == 2)
column.setMaxWidth(50);
}

Categories