Hi Vladimir,
In Swing, a transfer handler is responsible to provide the transfer
data. The default implementation for JTable just uses
table.getValueAt(row, column) to construct the transfer data, i.e.
renderers are not considered. For more information you can find Swing's
default implementation in the class
javax.swing.plaf.basic.BasicTableUI.TableTransferHandler class.
In ULC you can write an extension to have custom transfer behavior. The
code at the end of my mail shows such an extension that considers renderers.
Regards Dany
import com.ulcjava.base.application.AbstractApplication;
import com.ulcjava.base.application.ULCFrame;
import com.ulcjava.base.application.ULCTable;
import com.ulcjava.base.application.table.AbstractTableModel;
import com.ulcjava.base.application.table.ITableModel;
import com.ulcjava.base.client.UITable;
import com.ulcjava.base.development.DevelopmentRunner;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import javax.swing.table.TableCellRenderer;
import java.awt.Component;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.util.Date;
public class TableToExcelSnippet extends AbstractApplication {
public void start() {
ULCFrame frame = new ULCFrame("Snippet");
frame.setDefaultCloseOperation(ULCFrame.TERMINATE_ON_CLOSE);
frame.getContentPane().add(new ULCSnippetTable(new SnippetModel()));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
DevelopmentRunner.setApplicationClass(TableToExcelSnippet.class);
DevelopmentRunner.main(args);
}
public static class ULCSnippetTable extends ULCTable {
public ULCSnippetTable(ITableModel model) {
super(model);
}
protected String typeString() {
return UISnippetTable.class.getName();
}
}
public static class UISnippetTable extends UITable {
protected void postInitializeState() {
super.postInitializeState();
getBasicTable().setTransferHandler(new
SnippetTransferHandler());
}
}
public static class SnippetTransferHandler extends TransferHandler {
protected Transferable createTransferable(JComponent component) {
StringBuffer data = new StringBuffer();
JTable table = (JTable)component;
for (int i = 0; i < table.getRowCount(); i++) {
for (int j = 0; j < table.getColumnCount(); j++) {
if (j > 0) {
data.append('\t');
}
data.append(toTransferValue(table, i, j));
}
data.append('\n');
}
return new StringSelection(data.toString());
}
private Object toTransferValue(JTable table, int row, int column) {
TableCellRenderer renderer = table.getCellRenderer(row, column);
Component rendererComponent =
table.prepareRenderer(renderer, row, column);
if (rendererComponent instanceof JLabel) {
JLabel rendererLabel = (JLabel)rendererComponent;
return rendererLabel.getText();
} else {
return table.getValueAt(row, column);
}
}
public int getSourceActions(JComponent c) {
return COPY;
}
}
public static class SnippetModel extends AbstractTableModel {
public Object getValueAt(int row, int column) {
switch (column) {
case 1:
return new Date();
default:
return "foo";
}
}
public int getRowCount() {
return 20;
}
public int getColumnCount() {
return 5;
}
public Class getColumnClass(int columnIndex) {
switch (columnIndex) {
case 1:
return Date.class;
default:
return Object.class;
}
}
}
}
Vladimír Turek wrote:
Hello to all,
The problem I encounter when I try to copy lines from ULCTable to MS
Excel with Ctrl+C and Ctrl+V, is that copied data into clipboard
contains number and date format without accepting renderers in table
columns. And Czech Excel shows pasting number and date as text, not as
requested. I have table with many rows and need to copy lines only on
client without any server roundtrip. I find out that a value for copy
is acquiring in UITableModelAdapter's getValueAt(int rowIndex, int
columnIndex) method.
Expected result:
31.7.2003 2 848,00 do roku 2005
31.5.2003 34 709,00 do roku 2005
13.6.2003 450,00 do roku 2005
Actual result:
Thu Jul 31 00:00:00 CEST 2003 2848.00 do roku 2005
Sat May 31 00:00:00 CEST 2003 34709.00 do roku 2005
Fri Jun 13 00:00:00 CEST 2003 450.0 do roku 2005
This is what I have in my code ...
private void updateTableLook() {
...
for (int i = 0; i < _tableModel.getColumnCount(); i++) {
ULCTableColumn column = _table.getColumnModel().getColumn(i);
// column renderer's
String typ = _tableModel.getColumnTyp(i);
if (typ.equals("B")) {
column.setCellRenderer(new BooleanRenderer());
} else if (typ.equals("D")) {
column.setCellRenderer(new DateRenderer());
} else if (typ.equals("T")) {
column.setCellRenderer(new DateTimeRenderer());
} else if (typ.equals("N")) {
column.setCellRenderer(new DecimalRenderer());
} else if (typ.equals("I")) {
column.setCellRenderer(new IntegerRenderer());
} else if (typ.equals("L")) {
column.setCellRenderer(new LongRenderer());
}
_table.repaint();
}
public class DateRenderer extends DefaultTableCellRenderer {
public DateRenderer() {
setDataType(new ULCCzDateDataType());
}
}
public class ULCCzDateDataType extends ULCDateDataType {
public static final String DEFAULT_FORMAT = "d.M.yyyy";
public ULCCzDateDataType(String format) {
if (format != null && !format.equals("")) {
super.setFormatString(format);
} else {
setFormatString(DEFAULT_FORMAT); }
}
public ULCCzDateDataType() {
this(DEFAULT_FORMAT);
}
protected String typeString() {
return "cz.cosma.cis.base.client.util.datatype.UICzDateDataType";
}
}
public class UICzDateDataType extends
com.ulcjava.base.client.datatype.UIDateDataType {
}
Extending UICzDateDataType's method convertToString(Object object,
boolean forEditing) don't affect the result.
ULC 6.1.3 on Windows 2000, Java 1.5.0_04 and Czech version of Excel.
Thanks and regards,
Vladimir Turek
_______________________________________________
ULC-developer mailing list
[email protected]
http://lists.canoo.com/mailman/listinfo/ulc-developer
_______________________________________________
ULC-developer mailing list
[email protected]
http://lists.canoo.com/mailman/listinfo/ulc-developer