I'm using NatTable to display table data, the table can be sorted and filtered. Since the table is quite large I also used GlazedList. I need to be able to remove columns after sorting and filtering. As I tried, I could only remove the content of the table but the header remains there. The column header is nested in many layers and I don't know I could affect or trigger a refresh on it.
My code are mostly from the examples with slight modifications:
set up the layers:
ModelProvider mp = new ModelProvider();
// property names of the Person class
this.propertyNames = new String[this.attributeNames.size() + 1];
this.propertyNames[0] = "Entry";
for (int i = 0; i < this.attributeNames.size(); i++) {
this.propertyNames[i + 1] = this.attributeNames.get(i);
}
// mapping from property to label, needed for column header labels
this.propertyToLabelMap = new HashMap<String, String>();
for (String str : this.propertyNames) {
this.propertyToLabelMap.put(str, str);
}
IColumnPropertyAccessor<GazEntry> columnPropertyAccessor = new GazColumnPropertyAccessor();
final BodyLayerStack<GazEntry> bodyLayerStack = new BodyLayerStack<GazEntry>(
mp.entrylines, columnPropertyAccessor);
IDataProvider columnHeaderDataProvider =
new DefaultColumnHeaderDataProvider(this.propertyNames, this.propertyToLabelMap);
final DataLayer columnHeaderDataLayer =
new DataLayer(columnHeaderDataProvider);
final ColumnHeaderLayer columnHeaderLayer =
new ColumnHeaderLayer(columnHeaderDataLayer, bodyLayerStack, bodyLayerStack.getSelectionLayer());
SortHeaderLayer<GazEntry> sortHeaderLayer =
new SortHeaderLayer<GazEntry>(
columnHeaderLayer,
new GlazedListsSortModel<GazEntry>(
bodyLayerStack.getSortedList(),
columnPropertyAccessor,
configRegistry,
columnHeaderDataLayer));
// build the column header layer
// Note: The column header layer is wrapped in a filter row composite.
// This plugs in the filter row functionality
FilterRowHeaderComposite<GazEntry> filterRowHeaderLayer = new FilterRowHeaderComposite<GazEntry>(
new DefaultGlazedListsFilterStrategy<GazEntry>(
bodyLayerStack.getFilterList(), columnPropertyAccessor,
configRegistry), sortHeaderLayer,
columnHeaderDataLayer.getDataProvider(), configRegistry);
// build the row header layer
IDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
bodyLayerStack.getBodyDataProvider());
DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(
rowHeaderDataProvider);
final ILayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer,
bodyLayerStack, bodyLayerStack.getSelectionLayer());
// build the corner layer
IDataProvider cornerDataProvider = new DefaultCornerDataProvider(
columnHeaderDataProvider, rowHeaderDataProvider);
DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer,
filterRowHeaderLayer);
IRowDataProvider<GazEntry> bodyDataProvider = (IRowDataProvider<GazEntry>) bodyLayerStack.getBodyDataProvider();
bodyLayerStack.setConfigLabelAccumulator(new CrossValidationLabelAccumulator(
bodyDataProvider));
// DataLayer bodyDataLayer = new DataLayer(bodyDataProvider);
bodyLayerStack.registerCommandHandler(new
DeleteRowCommandHandler<GazEntry>(bodyLayerStack.bodyData));
//TODO: register delete column.
bodyLayerStack.registerCommandHandler(new
DeleteColCommandHandler<GazEntry>(bodyLayerStack.bodyData));
and the command handler to delete a column
class DeleteColCommandHandler<T> implements ILayerCommandHandler<DeleteColCommand> {
private List<T> bodyData;
public DeleteColCommandHandler(List<T> bodyData) {
this.bodyData = bodyData;
}
#Override
public Class<DeleteColCommand> getCommandClass() {
return DeleteColCommand.class;
}
//TODO: delete column
#Override
public boolean doCommand(ILayer targetLayer, DeleteColCommand command) {
// convert the transported position to the target layer
if (command.convertToTargetLayer(targetLayer)) {
// remove the element
// this.bodyData.remove(command.getRowPosition());
SelectionLayer slayer = ((BodyLayerStack) targetLayer).getSelectionLayer();
int[] selected = slayer.getSelectedColumnPositions();
for (int index : selected) {
String colName = CopyOf_6031_GlazedListsFilterExample.this.propertyNames[index];
CopyOf_6031_GlazedListsFilterExample.this.attributeNames.remove(colName);
targetLayer.fireLayerEvent(new
ColumnDeleteEvent(targetLayer, index));
}
return true;
}
return false;
}
}
as said, this deletes the column content but leaves the header. Can anyone tell me how I can also remove the column header?
Do you really want to delete a column or do you simply want to hide a column? Because hiding would be much easier. Of course this depends on your use case and if your data model can be modified to really deleting a column.
Nevertheless, the DefaultColumnHeaderDataProvider does not support dynamic adding or removing columns as it is based on an array. For such an use case you need to provide a custom IDataProvider for the column header. The NatTable Examples application contains an example for that under Tutorial Examples -> Data -> DynamicColumnExample.
You simply need to implement an IDataProvider that is based on a List rather than an array, so elements can be removed and the size modified.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 months ago.
Improve this question
I have an excel file, i have to parse to list of objects:
excel:
excel
my pojo:
my service:
public List<RegisterModel> parse(MultipartFile file) throws IOException {
Workbook workbook = new HSSFWorkbook(file.getInputStream());
Sheet worksheet = workbook.getSheetAt(0);
List<RegisterModel> registerModelList = new ArrayList<>();
RegisterModel registerModel = new RegisterModel();
for (int i = 3; i < worksheet.getPhysicalNumberOfRows(); i++) {
Row row = worksheet.getRow(i);
String headers = String.valueOf(row.getCell(0));
String values = String.valueOf(row.getCell(1));
if (headers.equals("OPERDAY")){
registerModel.setDate(values);
}
if (headers.equals("SUIP")){
registerModel.setSuip(values);
}
if (headers.equals("STATE")){
registerModel.setSuip(values);
}
if (headers.equals("NOM_OPER")){
registerModel.setTransactionID(values);
}
registerModelList.add(registerModel);
}
System.out.println(registerModelList);
return registerModelList;
}
but it is not works(
result: values are duplicate
[RegisterModel(date=2022-03-01T23:48:47, suip=Проведён, state=null, transactionID=1888314188),
RegisterModel(date=2022-03-01T23:48:47, suip=Проведён, state=null, transactionID=1888314188),
RegisterModel(date=2022-03-01T23:48:47, suip=Проведён, state=null, transactionID=1888314188)]
The issue is caused by only creating a single instance of registerModel outside of your for loop. You just keep editing that object over and over instead of creating new instances of it. The way to solve this is to create a new instance of registerModel every time a previous object is completed or before a new object is started.
There are multiple ways to achieve this by using nested loops or incrimenting your for loop by 5 at a time (rows in your order) and specifically keeping track of where items are at. However, if we assume that the last bit of data in an order is the "NOM_OPER" row then we can do the following quick and easy solution.
This is the code that has been changed:
if (headers.equals("NOM_OPER")){
registerModel.setTransactionID(values);
//Now that the object is complete we can add it to the list (moved here from below)
registerModelList.add(registerModel);
//The lastly we NEED to create a new instance of registerModel for the next order to use
registerModel = new RegisterModel();
}
//Remove the below line after the if statements.
//You should only add the model to the list once the object is complete. Don't add it on every row.
//registerModelList.add(registerModel);
And the complete method looks like this:
public List<RegisterModel> parse(MultipartFile file) throws IOException {
Workbook workbook = new HSSFWorkbook(file.getInputStream());
Sheet worksheet = workbook.getSheetAt(0);
List<RegisterModel> registerModelList = new ArrayList<>();
RegisterModel registerModel = new RegisterModel();
for (int i = 3; i < worksheet.getPhysicalNumberOfRows(); i++) {
Row row = worksheet.getRow(i);
String headers = String.valueOf(row.getCell(0));
String values = String.valueOf(row.getCell(1));
if (headers.equals("OPERDAY")){
registerModel.setDate(values);
}
if (headers.equals("SUIP")){
registerModel.setSuip(values);
}
if (headers.equals("STATE")){
registerModel.setSuip(values);
}
if (headers.equals("NOM_OPER")){
registerModel.setTransactionID(values);
//Now that the object is complete we can add it to the list (moved here from below)
registerModelList.add(registerModel);
//The lastly we NEED to create a new instance of registerModel for the next order to use
registerModel = new RegisterModel();
}
//Remove the below line after the if statements.
//You should only add the model to the list once the object is complete. Don't add it on every row.
//registerModelList.add(registerModel);
}
System.out.println(registerModelList);
return registerModelList;
}
I am having a table which is getting data from database. But I want to add a row with checkbox having attributes as name But everytime I run the program it show the value as
javax.swing.JCheckBox[ , 0, 0, 0x0, invalid, alignmentX = 0.0, alignmentY = 0.5, border = java................
Here is the code.
while(rs.next()) {
Vector row = new Vector();
String name = rs.getString("name");
String catid = rs.getString("catalogid");
String brand = rs.getString("brand");
String counter = rs.getString("counter");
String qty = rs.getString("qty");
String price = rs.getString("column_price");
row.add(name);
row.add(catid);
row.add(brand);
row.add(counter);
row.add(qty);
row.add(price);
cb = new JCheckBox(name, true);
row.add(cb);
model.addRow(row);
}
You don't add components to the TableModel of a JTable. You add data and use renderers to render the data.
So in your case you need to:
add Boolean.TRUE as the data to the TableModel.
override the getColumnClass(...) method of the TableModel to return Boolean.class so the table can render the Boolean object as a check box.
Read the Swing tutorial on How to Use Tables for more information and examples to get you started.
I want to add new record in the grid view which is getting displayed on the UI.
I m working on some project in java spring mvc.
There are some already existing records from which some are primary keys and they are not enabled at the time of editing.
So when I click on Add button, controls goes to those which field which are not primary keys means those fields are editable.
So I want to make editable primary keys at the time of adding new record.
public static List<SelectListItem> GetDropDownList<T>(
string text, string value, string selected) where T : class
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem { Text = "-Please select-", Value = string.Empty });
IQueryable<T> result = Db.Repository<T>();
var lisData = (from items in result
select items).AsEnumerable().Select(m => new SelectListItem
{
Text = (string)m.GetType().GetProperty(text).GetValue(m),
Value = (string)m.GetType().GetProperty(value).GetValue(m),
Selected = (selected != "") ? ((string)
m.GetType().GetProperty(value).GetValue(m) ==
selected ? true : false) : false,
}).ToList();
list.AddRange(lisData);
return list;
}
}
I am working with apose words java recently.
In my first page I have a table need to merge, which can grow any size, no fixed number of rows and at the end of my first page, I want to keep some content (for example contact details) to be fixed. (Note: I can't keep contact details in Footer or in foot note section because of some formatting I need to ensure which can't maintain in footer or foot note section)
On growing of table as many rows, My content is going down, But I want to fix it at the end of my first page. if table grows bigger in size, wanted to skip the content and render table in next page.
is there any solution/work around for this?
My expected results are like below....
Page 1 Start
dynamic Table row1
dynamic Table row2
dynamic Table row3
Contact Details ,wanted to fix at the end of my first page
Page 1 end
Page 2 Start
dynamic table row 4
dynamic table row 5
........
For your scenario, ideally the contact details should be set in a footer. It is possible, but very risky.
First create a new document, either in Aspose.Words or MS Word, it will be used as a template.
Add a blank table on top
Add contact details, after the blank table
Add a bookmark, after the contact details
Now, using Aspose.Words, you can check the location of the bookmark, every time you are adding a new row in the table. If bookmark is at page 1, add new row to the first table. If bookmark is at page 2, add new row to the second table. Below is the sample code that adds rows to the table, keeping the contact details fixed on page 1.
Template document: Google drive link
Java source code is given below.
public static void main(String[] args)
{
try
{
String template = Common.DATA_DIR + "Contact Template.docx";
String saveDocument = Common.DATA_DIR + "Contact with tables.docx";
String bookmarkNameContact = "ContactEnd";
// Load the template
com.aspose.words.Document wordDoc = new com.aspose.words.Document(template);
DocumentBuilder builder = new DocumentBuilder(wordDoc);
// Find the contacts bookmark
com.aspose.words.Bookmark bookmarkContact = wordDoc.getRange().getBookmarks().get(bookmarkNameContact);
// Set the table with null
com.aspose.words.Table table = null;
// Add some rows
for (int i = 0; i < 50; i++)
{
// If contacts bookmark is on 1st page, add new rows to first table
if (getBookmarkPage(wordDoc, bookmarkContact) == 1)
{
table = (com.aspose.words.Table) wordDoc.getChild(NodeType.TABLE, 0, true);
} else
{
// If the contacts bookmark is on second page, add rows to second table
table = (com.aspose.words.Table) wordDoc.getChild(NodeType.TABLE, 1, true);
// If there is no second table, create it
if (table == null)
{
table = createNewTable(wordDoc, bookmarkContact);
}
}
// Add rows dynamically to either first or second table
addRow(wordDoc, table, "some text " + i);
}
// Save the document
wordDoc.save(saveDocument);
} catch (Exception ex)
{
System.err.println(ex.getMessage());
}
}
private static com.aspose.words.Table createNewTable(com.aspose.words.Document wordDoc, com.aspose.words.Bookmark bookmarkContact) throws Exception
{
// Get the first table and clone it to create the second one
com.aspose.words.Table firstTable = (com.aspose.words.Table) wordDoc.getChild(NodeType.TABLE, 0, true);
com.aspose.words.Table table = (com.aspose.words.Table) firstTable.deepClone(true);
// Add the second table after the bookmark
bookmarkContact.getBookmarkEnd().getParentNode().getParentNode().appendChild(table);
// Delete all its rows
table.getRows().clear();
return table;
}
// Add a new row to the table
private static void addRow(com.aspose.words.Document wordDoc, com.aspose.words.Table table, String text)
{
// Create a new row
com.aspose.words.Row row = new com.aspose.words.Row(wordDoc);
row.getRowFormat().setAllowBreakAcrossPages(true);
// Add it to the table
table.appendChild(row);
// Add cells to the row
for (int iCell = 0; iCell < 4; iCell++)
{
// Create a new cell and set text inside it
com.aspose.words.Cell cell = new com.aspose.words.Cell(wordDoc);
cell.appendChild(new com.aspose.words.Paragraph(wordDoc));
cell.getFirstParagraph().appendChild(new Run(wordDoc, text));
cell.getFirstParagraph().getParagraphFormat().setSpaceAfter(0);
row.appendChild(cell);
}
}
private static int getBookmarkPage(com.aspose.words.Document wordDoc, com.aspose.words.Bookmark bookmarkContact) throws Exception
{
// Find the page number, where our contacts bookmark is
LayoutCollector collector = new LayoutCollector(wordDoc);
return collector.getStartPageIndex(bookmarkContact.getBookmarkEnd());
}
I work with Aspose as Developer Evangelist.
I've been searching through this website for numerous hours now on how to get my button to an a row to an already existing table, this table created by simply clicking the swing Controls, and adding a table and altering the fields through the properties.
The table's variable name is 'table'.
And when confronted with this line of code:
table.getModel().insertRow(table.getRowCount(),new Object[]{nome[i],data[i]});
The 'insertRow' part is redded and I can't seem to fix it.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String direcdate=direc1.getText();
File folder = new File(direcdate);
File[] listOfFiles=folder.listFiles();
String[] nome = new String[250];
String[] data = new String[250];
int i=0;
for (File listOfFile : listOfFiles) {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
if (listOfFile.isFile()) {
nome[i]= listOfFile.getName ();
data[i] =sdf.format(listOfFile.lastModified());
i++;
}
else if (listOfFile.isDirectory()) {
nome[i]= "Folder: " + listOfFile.getName ();
data[i] =sdf.format(listOfFile.lastModified());
i++;
}
}
for(int increm=0;increm<i;increm++)
{
table.getModel().insertRow(table.getRowCount(),new Object[]{nome[i],data[i]});
}
}
Any ideas or suggestions?
EDIT: where the table model is located:
public class GAPAC_TESTE extends javax.swing.JFrame {
public GAPAC_TESTE() {
initComponents();
ultimaalt.setText("0");
jTextPane2.setText("Após escolher a diretoria, escolha uma das opções.");
DefaultTableModel model = new javax.swing.table.DefaultTableModel();
table = new javax.swing.JTable(model);
}
table.getModel().
That method return a TableModel. Did you look at the API for the TableModel interface? It does not contain an insertRow(...) method.
The DefaultTableModel has the insertRow(...) method. So assuming your table is using a DefaultTableModel the code would be:
DefaultTableModel model = (DefaultTableMode)table.getModel();
model.insertRow(...);
Don't always write you code in a single statmentment. Break the statement up into multiple statements so you understand exactly which part of the statement causes the problem and it makes sure you assign the variable to the proper class.
If you implement a TableModel, you will be able to exactly determine how data is added and which data types are displayed in your table.