JTable sorting and Jasper report output - java

In my one of Java swing desktop based applications, I am using a JTable and I added the sorting functionality for a column. I need to sort it according to the number values added by the user and then get the jasper report output.
Currently after the sorting and print the report, the report is not showing the sorted order. But the order when the values taken from the DB. How can I print the report which the user's table sorting order?
This is my jasper report generating code
try {
DefaultTableModel de = (DefaultTableModel)Dashboard.catalogTbl.getModel();
JRTableModelDataSource jr = new JRTableModelDataSource(de);
String reportName = reportPath + "reports/AuctionSale/Catalogue/catalouge_frm_tbl.jrxml";
String compiledName = reportPath + "reports/AuctionSale/Catalogue/catalouge_frm_tbl.jasper";
Map<String, Object> params = new HashMap<String, Object>();
params.put("Lot_No", "Lot No");
params.put("Mark", "Mark");
params.put("Invoice", "Invoice");
params.put("Grade", "Grade");
params.put("Weight", "Weight");
params.put("Price", "Price");
params.put("Buyer", "Buyer");
JasperCompileManager.compileReportToFile(reportName, compiledName);
JasperPrint jasperPrint = JasperFillManager.fillReport(compiledName, params, jr);
JasperViewer.viewReport(jasperPrint, false);
} catch (Exception e) {
e.printStackTrace();
}

I guess the report is generated based on the TableModel, while typical sorting only affect the JTable itself, not the model.
What you could do is decorate the table model which you pass to your report generator so that it takes over the ordering of your JTable. Something in the style of
public class TableModelDecorator implements TableModel{
private TableModel delegate;
private JTable table;
#Override
public Object getValueAt( int rowIndex, int columnIndex ) {
return delegate.getValueAt( table.convertRowIndexToView( rowIndex ), table.convertColumnIndexToView( columnIndex ) );
}
}
but then for all relevant methods.

#Robin answer is basically correct, just translating to jasper speak :-)
The "decorator" is a custom implementation of JRDataSource or (here) JRRewindableDataSource. Make it data-only and base on the table's RowSorter, something like (beware: just compiled, not tested!)
public class JRTableSorterDataSource implements JRRewindableDataSource {
private RowSorter<? extends TableModel> sorter;
private int currentRow = -1;
private HashMap<String, Integer> columnNames = new HashMap<String, Integer>();
public JRTableSorterDataSource(RowSorter<? extends TableModel> sorter) {
if (sorter == null) return; // do nothing, no sorter
this.sorter = sorter;
TableModel tableModel = sorter.getModel();
if (tableModel != null) {
for (int i = 0; i < tableModel.getColumnCount(); i++) {
this.columnNames.put(tableModel.getColumnName(i),
Integer.valueOf(i));
}
}
}
#Override
public Object getFieldValue(JRField field) throws JRException {
String fieldName = field.getName();
Integer columnIndex = this.columnNames.get(fieldName);
return sorter.getModel().getValueAt(sorter.convertRowIndexToModel(currentRow), columnIndex.intValue());
}
#Override
public boolean next() throws JRException {
if (sorter == null || sorter.getModel() == null)
return false;
this.currentRow++;
return (this.currentRow < sorter.getViewRowCount());
}
#Override
public void moveFirst() throws JRException {
this.currentRow = -1;
}
protected int getColumnIndex(JRField field) throws JRException {
String fieldName = field.getName();
Integer columnIndex = this.columnNames.get(fieldName);
if (columnIndex != null) {
return columnIndex;
} else if (fieldName.startsWith("COLUMN_")) {
return Integer.parseInt(fieldName.substring(7));
}
throw new JRException("Unknown column name : " + fieldName);
}
}
Then use it when setting up your report:
JRDataSource jr = new JRTableSorterDataSource(Dashboard.catalogTbl.getRowSorter());
/// ... same as your example
Edit
just a very quick runnable snippet (too lazy to do a full report, forgot how those files work ;-) - so here we create a table (with a standard SwingX model), create a dataSource on its RowSorter and loop over the values of the first column, no problem:
JTable table = new JXTable(new AncientSwingTeam());
JRDataSource source = new JRTableSorterDataSource(table.getRowSorter());
table.getRowSorter().toggleSortOrder(0);
JRField field = createField("First Name");
String firstNames = "First Name: ";
while (source.next()) {
firstNames += "\n " + source.getFieldValue(field);
}
LOG.info(firstNames);

Something late, but I hope it helps someone:
In this code, what I do is that after applying the filters in the jTable1, place the rows obtained in the auxiliary model.
Then I assigned the auxiliary model to the auxiliary table. And that table is the one I'll send to JasperReports.
//** jTable1 is the table in the jFrame where the data is loaded and I apply
//the RowFilter or RowSorter filters
DefaultTableModel dataModel_tableFiltered = null; //auxiliary model
JTable tableAuxiliary = null; //table where we will put the auxiliary model
public constructor {
        
    dataModel_tableFiltered = new DefaultTableModel ();
    // Set the number and name of the columns in the auxiliary model
    for (int i = 0; i <jTable1.getColumnCount(); i ++) {
        dataModel_tableFiltered.addColumn(jTable1.getColumnName (i));
    }
    
    tableAuxiliary = new JTable ();
}
private void btn_PrintActionPerformed (java.awt.event.ActionEvent evt) {
    fillModel_filtered ();
    try {
        Map params = new HashMap ();
        params.put ("nameCustomer", "**");
        JRDataSource dataSource = new JRTableModelDataSource (tableAuxiliary.getModel ());
        JasperPrint print = JasperFillManager.fillReport (reportPath, params, dataSource);
        JasperViewer.viewReport (print, false); // true == Exit on Close
    } catch (JRException ex) {
        ex.printStackTrace ();
    }
 }
// Put resulting rows in the model after applying filters in jTable1
public void fillModel_filtered () {
    dataModel_tableFiltered.setRowCount (0); // Empty rows of the model
    for (int i = 0; i <jTable1.getRowCount (); i ++) {
        Object row [] = new Object [jTable1.getColumnCount ()];
        for (int j = 0; j <jTable1.getColumnCount (); j ++) {
            row [j] = jTable1.getValueAt (i, j);
        }
        dataModel_tableFiltered.addRow (row);
    }
    tableAuxiliary.setModel(dataModel_tableFiltered); // Very Important
}

Related

Null Pointer Exception importing Web elements to Excel [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm stuck on a Null Pointer Exception problem. The tests are run through JUnit, but I didn't manage to debug properly and find out the reason of it.
Test class
ExcelActions excelActions;
Excel_Import excel_import;
#Test
public void addResultsToExcel() throws InterruptedException {
searchAfterLogin(); // works fine until the next method
excelActions.addToExcel(); //thats where NPE begins...
excel_import.importExcel(excelActions.addToExcel());
}
Excel Action (Webdriver part)
public class ExcelActions extends BaseAction {
public ExcelActions(WebDriver driver) { super(driver); }
public Map<String, Object[]> addToExcel(){
String beforeXpath_pageName = "//*[#id=\"mw-content-
text\"]/div[3]/ul/li[";
String afterXpath_pageName = "]/div[1]/a";
int rowCount ;
rowCount = 20;
Map<String, Object[]> data = new TreeMap<String, Object[]>();
for(int i = 1; i <= rowCount; i++){
String actualXpath_pageName = beforeXpath_pageName + i +
afterXpath_pageName;
String pageName =
driver.findElement(By.xpath(actualXpath_pageName)).getText();
System.out.println(pageName);
data.put("" + i, new Object[]{pageName});
}
return data;
}
}
Excel import class
public class Excel_Import extends BaseAction {
public Excel_Import(WebDriver driver) { super(driver); }
public void importExcel(Map<String, Object[]> data) {
XSSFWorkbook workbook = new XSSFWorkbook();
//Create a blank sheet
XSSFSheet sheet = workbook.createSheet("Data");
//Iterate over data and write to sheet
Set<String> keyset = data.keySet();
int rownum = 0;
for (String key : keyset)
{
//create a row of excel sheet
Row row = sheet.createRow(rownum++);
//get object array of particular key
Object[] objArr = data.get(key);
int cellnum = 0;
for (Object obj : objArr)
{
Cell cell = row.createCell(cellnum++);
if (obj instanceof String)
{
cell.setCellValue((String) obj);
}
else if (obj instanceof Integer)
{
cell.setCellValue((Integer) obj);
}
}
}
try
{
//Write the workbook in file system
FileOutputStream out = new FileOutputStream(new
File("D:\\Projects\\Cucumber\\src\\main\\resources\\ImportedResults.xlsx"));
workbook.write(out);
out.close();
System.out.println("howtodoinjava_demo.xlsx written successfully on
disk.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Could you guys have a look at it?
The field:
ExcelActions excelActions;
is not initialized. You should assign an instance of ExcelActions to it, e.g.:
ExcelActions excelActions = new ExcelActions(someWebDriverMock);
It is not enough to declare a field in a class. You need some specific object to be assigned to it, otherwise it will be null.

How to use result set of executeQuery() of one method to different methods

I have one method called ExecuteQuery which is responsible for executing the query.
It is defined as :
public int ExecuteQuery(String itemCode) {
ps = jdbcConnection.prepareStatement(SomeQuery);
rs = ps.executeQuery();
}
I have three different methods in which I want to use the same result set. Obviosuly, I do not want to execute the same query thrice since it hampers my time complexity.
private Map<String, ItemRelation> loadItemRelations(String itemCode) throws PosfException {
Map<String, ItemRelation> relations = new LinkedHashMap<String, ItemRelation>();
try {
**while (rs.next()) {**
How can I use rs in this function so that it loops with the result which I got while executing rs=ps.executeQuery();
I have three functions which need same query results to perform different actions.
You have two options:
Normally, a ResultSet is TYPE_FORWARD_ONLY. Change that to TYPE_SCROLL_INSENSITIVE (or TYPE_SCROLL_SENSITIVE) by specifying that option on the prepareStatement() call. That way you can call beforeFirst() to reset the ResultSet to the beginning and iterate it again.
Load all the rows from the ResulSet into memory, e.g. as a List<MyRowClass>. Then you can iterate that list as many times as needed, and isolate the JDBC calls to a single place. Advantage: Column values are typed, and things like handling of nulls for primitives (wasNull()) only needs to be done in one place.
I'd suggest going with option 2.
This is my solution.
First you need to save the result to other type (like TableModel) and then you data in TableModel. Like Datatable in C#.
This my class. Hope to help you
package saoviet.amisystem.model.datacollection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Vector;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class DataTable {
public TableModel dataTable;
public TableModel getDataTable() {
return dataTable;
}
private Vector<String> columnNames;
private Vector<Vector<Object>> rows = new Vector<Vector<Object>>();
private TableModel resultSetToTableModel(ResultSet rs) {
try {
ResultSetMetaData metaData = rs.getMetaData();
int numberOfColumns = metaData.getColumnCount();
// Get the column names
for (int column = 0; column < numberOfColumns; column++) {
this.columnNames.addElement(metaData.getColumnLabel(column + 1));
}
// Get all rows.
while (rs.next()) {
Vector<Object> newRow = new Vector<Object>();
for (int i = 1; i <= numberOfColumns; i++) {
newRow.addElement(rs.getObject(i));
}
this.rows.addElement(newRow);
}
return new DefaultTableModel(rows, this.columnNames);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public DataTable() {
}
public DataTable(ResultSet result) throws SQLException {
this.columnNames = new Vector<String>();
this.dataTable = this.resultSetToTableModel(result);
}
public String getValue(int rowIndex, int columnIndex) {
return this.dataTable.getValueAt(rowIndex, columnIndex).toString();
}
public String getValue(int rowIndex, String columnName) {
return this.getValue(rowIndex, this.columnNames.indexOf(columnName));
}
public void addRow(Object[] obj) {
Vector<Object> newRow = new Vector<Object>();
String columIndex = "";
if (this.columnNames == null) {
this.columnNames = new Vector<String>();
for (int i = 0; i < obj.length; i++) {
columIndex = "" + i;
this.columnNames.addElement(columIndex);
}
}
for (int i = 0; i < obj.length; i++) {
newRow.addElement(obj[i]);
}
this.rows.addElement(newRow);
this.dataTable = new DefaultTableModel(rows, this.columnNames);
}
public int rowCount() {
return this.rows.size();
}
}

Method does not load data to jTable when said method is outside of the main GUI class

The problem with my program is that once the "getMP3Tags" method is removed from the main class which is called ""musicManagerUI", and placed within it's own class, the method does not send anything over to the appropriate methods in the "musicManagerUI" class. However, if the "getMP3Tags" method is placed within the "musicManagerUI" class then everything works perfectly. I want to know why this happens and if anyone can help me to resolve this issue, as I don't want to cluster up the "musicManagerUI" class with loads of methods.
Here is the constructor for the main class "musicManagerUI":
public musicManagerUI() {
super ("Music Manager");
initComponents();
handlerClass handler = new handlerClass();
jMenuItem5.addMouseListener(handler);
}
Here is one the four methods which prints out data to the jTable:
public void printArtistName(ArrayList arrayOfArtistNames)
{
DefaultTableModel model = (DefaultTableModel) jTable2.getModel();
if (arrayOfArtistNames == null) {model.setValueAt("No Artist Names Found", 0, 0);}
else {
Object [] rowData;
rowData = new Object[3];
for (Object x : arrayOfArtistNames)
{
model.addRow(rowData);
model.setValueAt(x, counterArtist, 0);
counterArtist++;
}
}
}
Here is the code for the mousepressed handler method:
public void mousePressed(MouseEvent e) {
DefaultTableModel model = (DefaultTableModel) jTable2.getModel();
if (counterArtist == 0){}
else if (counterArtist > 0) {
model.setRowCount(0);
counterArtist = 0; counterTitle = 0; counterAlbum = 0; genre = 0;}
String FILE_DIR = "C:\\Users\\Hazzy\\Desktop\\test-data\\";
String FILE_TEXT_EXT = ".mp3";
findCertainExtension fw = new findCertainExtension();
try {
fw.getMP3Tags(FILE_DIR);
} catch (IOException ex) {
System.err.println(" Could Not read file in ");
} catch (TagException ex) {
System.err.println(" Could Not find tag");
}
}
And finally the "getMP3Tags" method:
public void getMP3Tags( String path ) throws IOException, TagException,
try{
File root = new File( path );
File[] list = root.listFiles();
ArrayList addArtistTitle = new ArrayList();
ArrayList addTrackTitle = new ArrayList();
ArrayList addAlbumTitle = new ArrayList();
ArrayList addGenre = new ArrayList();
if (list == null) return;
for ( File f : list ) {
if ( f.isDirectory()) {
getMP3Tags( f.getAbsolutePath() );
}
else if (!f.getAbsoluteFile().toString().toLowerCase().endsWith("mp3"))
{
getMP3Tags(f.getAbsolutePath());
}
else{
musicManagerUI setFields = new musicManagerUI ();
//System.out.println(f.getAbsoluteFile());
for (Object x : list) {}
MP3File mp3file = new MP3File(f.getAbsoluteFile());
ID3v2_2 name = (ID3v2_2) mp3file.getID3v2Tag();
if (name.getLeadArtist().isEmpty() == true){ name.setLeadArtist("Unknown");}
else if (name.getSongTitle().isEmpty() == true) {name.setSongTitle("Unknown");}
else if (name.getSongGenre().isEmpty() == true) {name.setSongGenre("Unknown");}
else if (name.getAlbumTitle().isEmpty() == true) {name.setAlbumTitle("Unknown");}
addArtistTitle.add(name.getLeadArtist());
addTrackTitle.add(name.getSongTitle());
addAlbumTitle.add(name.getAlbumTitle());
addGenre.add(name.getSongGenre());
}
}
musicManagerUI sendTrackInfo = new musicManagerUI();
sendTrackInfo.printArtistName(addArtistTitle);
sendTrackInfo.printTrackTitle(addTrackTitle);
sendTrackInfo.printAlbumTitle(addAlbumTitle);
sendTrackInfo.printGenre(addGenre);
}
catch(NullPointerException e){
System.err.println("Unknown Artist");
//return;
}
}
}
For this program I am using the ID3 Tagging Library/API. If you need the full code then please email me. Thanks in advance.
Some other sources which may be useful:
JTable does not show anything?
Loading Java JTable: Why does it not work?
My first thought is that in your getMP3Tags method you are calling
musicManagerUI setFields = new musicManagerUI ();
Which is creating a new instance of the musicManagerUI which has no relationship to the one that is on the screen...
What you might consider doing is passing a reference of the current instance of musicManagerUI to the method instead...
fw.getMP3Tags(FILE_DIR, this);
Assuming this is an instance of musicManagerUI which is actually been displayed...
ps- I should mention that you are actually create another instance of musicManagerUI in the getMP3Tags...
musicManagerUI sendTrackInfo = new musicManagerUI();

How to add columns to the new page in JasperReports report when exceed the width of page?

I create dynamically report as JasperDesign which every time has different number of columns.
Sometimes number of columns is so much that is not possible to display on one page.
I want to put this extra columns plus first two columns to the new page at the print time.
I have tried this by columnHeaderband.setSplitType(JRBand.SPLIT_TYPE_IMMEDIATE);
I use JasperReports 5.4.5 and Java 1.7
Dose any one know how to do it?
public class CarPlanDynamicReportCreator {
private static JRDataSource dataSource;
private static List<Map<String, String>> listOfExtractedMap;
private static final Boolean EMPTY_BAND = true;
private static List<String> fieldNameList;
private static List<String> remarkList;
public static void compile(DefaultTableModel tableModel, String title, String name, String id) throws JRException {
dataSource = createReportDataSource(tableModel);
JasperDesign jasperDesign = getJasperDesign(tableModel);
Map<String, Object> parameters = retrieveParameter(title, name, id);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
Report report = new Report(jasperPrint);
report.viewWithMaximumWindowSize();
}
public static JasperDesign getJasperDesign(DefaultTableModel tableModel) throws JRException {
//JasperDesign
JasperDesign jasperDesign = new JasperDesign();
jasperDesign.setName("The dynamically generated report");
jasperDesign.setPageWidth(842);
jasperDesign.setPageHeight(595);
jasperDesign.setOrientation(JRReport.ORIENTATION_LANDSCAPE);
jasperDesign.setColumnWidth(802);
jasperDesign.setColumnSpacing(2);
jasperDesign.setLeftMargin(20);
jasperDesign.setRightMargin(20);
jasperDesign.setTopMargin(20);
jasperDesign.setBottomMargin(20);
jasperDesign.setTitleNewPage(false);
jasperDesign.setFloatColumnFooter(true);
jasperDesign.setSummaryNewPage(false);
jasperDesign.addStyle(JasperDesignUtil.retrieveNormalStyle());
jasperDesign.addStyle(JasperDesignUtil.retrieveBoldStyle());
jasperDesign.addStyle(JasperDesignUtil.retrieveItalicStyle());
//Parameters
JasperDesignUtil.addParameters(jasperDesign, tableModel);
//Fields
JasperDesignUtil.addFields(jasperDesign, tableModel, fieldNameList);
//Variables
JasperDesignUtil.addVariables(jasperDesign, tableModel);
//Page header
JasperDesignUtil.addPageHeader(jasperDesign, tableModel, !EMPTY_BAND);
//Column header
JasperDesignUtil.addColumnHeader(jasperDesign, tableModel, !EMPTY_BAND);
//Detail band
JasperDesignUtil.addDetail(jasperDesign, tableModel, listOfExtractedMap, !EMPTY_BAND);
//Page footer
JasperDesignUtil.addPageFooter(jasperDesign, tableModel, !EMPTY_BAND);
//Summary
JasperDesignUtil.addSummary(jasperDesign, tableModel, remarkList, !EMPTY_BAND);
return jasperDesign;
}
private static JRDataSource createReportDataSource(DefaultTableModel tableModel) {
Map[] reportRows = initializeMapArray(tableModel);
return new JRMapArrayDataSource(reportRows);
}
public static Map<String, Object> retrieveParameter(String title, String name, String id) {
Map<String, Object> parameterMap = GenericsUtil.makeMap();
parameterMap.put("TITLE", title);
parameterMap.put("NAME", patient);
parameterMap.put("ID", patientId);
return parameterMap;
}
}
My util class:
public class JasperDesignUtil {
private static JRDesignBand band;
private static JRDesignField field;
private static JRDesignTextField textField;
private static JRDesignStaticText staticText;
private static JRDesignExpression expression;
// add Parameters
public static void addParameters(JasperDesign jasperDesign, DefaultTableModel tableModel) throws JRException {
JRDesignParameter parameter = new JRDesignParameter();
parameter.setName("TITLE");
parameter.setValueClass(java.lang.String.class);
JRDesignExpression expression = new JRDesignExpression();
expression.setText("");
expression.setValueClass(java.lang.String.class);
parameter.setDefaultValueExpression(expression);
jasperDesign.addParameter(parameter);
parameter = new JRDesignParameter();
parameter.setName("NAME");
parameter.setValueClass(java.lang.String.class);
expression = new JRDesignExpression();
expression.setText("");
expression.setValueClass(java.lang.String.class);
parameter.setDefaultValueExpression(expression);
jasperDesign.addParameter(parameter);
parameter = new JRDesignParameter();
parameter.setName("ID");
parameter.setValueClass(java.lang.String.class);
expression = new JRDesignExpression();
expression.setText("");
expression.setValueClass(java.lang.String.class);
parameter.setDefaultValueExpression(expression);
jasperDesign.addParameter(parameter);
}
// Add Fields
public static void addFields(JasperDesign jasperDesign, DefaultTableModel tableModel, List<String> fieldsName) throws JRException {
if (!fieldsName.isEmpty()) {
for (String name : fieldsName) {
field = new JRDesignField();
field.setName(name.replaceAll("\n", " "));
field.setValueClass(String.class);
jasperDesign.addField(field);
}
}
}
// Add Variables
public static void addVariables(JasperDesign jasperDesign, DefaultTableModel tableModel) throws JRException {
variable = new JRDesignVariable();
variable.setName("COLUMNS");
variable.setValueClass(java.lang.Integer.class);
variable.setCalculation(JRVariable.CALCULATION_COUNT);
expression = new JRDesignExpression();
expression.setValueClass(java.lang.Integer.class);
expression.setText("$V{COLUMN_COUNT}+1");
variable.setInitialValueExpression(expression);
variable.setResetType(JRVariable.RESET_TYPE_PAGE);
jasperDesign.addVariable(variable);
}
// Add ColumnHeader
public static void addColumnHeader(JasperDesign jasperDesign, DefaultTableModel tableModel, Boolean emptyBand) throws JRException {
if (emptyBand)
jasperDesign.setColumnHeader(retrieveEmptyBand(jasperDesign, 5));
else {
band = new JRDesignBand();
band.setHeight(25);
band.setSplitType(JRBand.SPLIT_TYPE_STRETCH);
int headerPosition = 0;
int columnCounter = 0;
for (JRField field : jasperDesign.getFields()) {
String fieldValue = field.getName();
String[] values = fieldValue.split(" ");
if (values.length != 1) {
String date = values[0];
String time = values[1];
fieldValue = "<html>".concat(date).concat("<BR>").concat(time).concat("</html>");
} else
fieldValue = "<html>".concat(fieldValue).concat("</html>");
int fieldLength = fieldValue.length();
headerPosition = columnCounter == 0 ? headerPosition : (columnCounter == 1 ? headerPosition + 100 : headerPosition + fieldLength);
JRDesignStaticText headerStaticText = new JRDesignStaticText();
headerStaticText.setX(headerPosition);
headerStaticText.setY(0);
headerStaticText.setWidth(columnCounter == 0 ? 100 : (columnCounter == 1 ? 34 : fieldLength + 7));
headerStaticText.setHeight(band.getHeight());
headerStaticText.setMode(JRElement.MODE_TRANSPARENT);
headerStaticText.setText(fieldValue);
headerStaticText.setPrintRepeatedValues(true);
headerStaticText.setPositionType(JRElement.POSITION_TYPE_FIX_RELATIVE_TO_TOP);
headerStaticText.setFontSize(8);
headerStaticText.setBold(true);
headerStaticText.setHorizontalAlignment(JRAlignment.HORIZONTAL_ALIGN_CENTER);
headerStaticText.setVerticalAlignment(JRAlignment.VERTICAL_ALIGN_MIDDLE);
headerStaticText.setMarkup("html");
headerStaticText.getLineBox().setLeftPadding(2);
headerStaticText.getLineBox().setRightPadding(2);
columnCounter++;
band.addElement(headerStaticText);
}
jasperDesign.setColumnHeader(band);
}
}
// Add Detail
public static void addDetail(JasperDesign jasperDesign, DefaultTableModel tableModel, List<Map<String, String>> maps, Boolean emptyBand) throws JRException {
if (emptyBand)
((JRDesignSection) jasperDesign.getDetailSection()).addBand(retrieveEmptyBand(jasperDesign, 5));
else {
band = new JRDesignBand();
band.setHeight(16);
int position = 0;
Map<String, String> headerMap = maps.get(0);
int columnCounter = 0;
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
//creating cell field on the detail band
String cellValue = "$F{".concat(entry.getKey().replaceAll("\n", " ")).concat("}");
int cellLength = cellValue.length();
position = columnCounter == 0 ? position : (columnCounter == 1 ? position + 100 : position + 27);
JRDesignTextField cellTextField = new JRDesignTextField();
cellTextField.setX(position);
cellTextField.setY(0);
cellTextField.setWidth(columnCounter == 0 ? 100 : (columnCounter == 1 ? 34 : 27));
cellTextField.setHeight(band.getHeight());
cellTextField.setPrintRepeatedValues(true);
cellTextField.setPositionType(JRElement.POSITION_TYPE_FIX_RELATIVE_TO_TOP);
cellTextField.setFontSize(8);
cellTextField.setHorizontalAlignment(JRAlignment.HORIZONTAL_ALIGN_CENTER);
cellTextField.setHorizontalAlignment(columnCounter == 0 ? JRAlignment.HORIZONTAL_ALIGN_LEFT : JRAlignment.HORIZONTAL_ALIGN_CENTER);
cellTextField.setVerticalAlignment(JRAlignment.VERTICAL_ALIGN_MIDDLE);
cellTextField.setStretchType(JRElement.STRETCH_TYPE_RELATIVE_TO_TALLEST_OBJECT);
cellTextField.setStretchWithOverflow(true);
cellTextField.setPositionType(JRElement.POSITION_TYPE_FLOAT);
JRDesignExpression cellExpression = new JRDesignExpression();
cellExpression.setValueClass(String.class);
cellExpression.setText(cellValue);
cellTextField.setExpression(cellExpression);
if (columnCounter == 0)
cellTextField.getLineBox().getRightPen().setLineWidth(1);
if (columnCounter != 0) {
cellTextField.setBold(true);
if (columnCounter % 2 != 0) {
cellTextField.setBackcolor(UIWebLook.secondary_4);
cellTextField.setMode(JRElement.MODE_OPAQUE);
}
}
band.addElement(cellTextField);
columnCounter++;
}
band.addElement(retrieveLine(0, 0, jasperDesign.getColumnWidth(), 0, JRGraphicElement.FILL_SOLID));
((JRDesignSection) jasperDesign.getDetailSection()).addBand(band);
}
}
private static JRDesignBand retrieveEmptyBand(JasperDesign jasperDesign, int height) {
band = new JRDesignBand();
band.setHeight(height);
band.addElement(retrieveLine(0, 0, jasperDesign.getColumnWidth(), 0, JRGraphicElement.FILL_SOLID));
return band;
}
public static JRDesignElement retrieveLine(int positionX, int positionY, int width, int height, #Nullable Byte fill) {
JRDesignLine line = new JRDesignLine();
line.setX(positionX);
line.setY(positionY);
line.setWidth(width);
line.setHeight(height);
line.setBackcolor(Color.white);
line.setForecolor(Color.black);
line.setPositionType(JRElement.POSITION_TYPE_FLOAT);
line.setFill(fill == null ? JRGraphicElement.PEN_NONE : fill);
return line;
}
}
Use subreports, that is the best way to this.

Reading multiple line textfile to database

I have a text file that looks like this:
Person1 Name
Person1 age
Person1 Address
Person2 Name
Person2 age
Person2 Address
Person3 Name
Person2 age
Person3 Address
and I need to get the information to a database.
I have the database connection and know how to enter the info into the database once I have the lines put into the correct variables . . . but how do I get java to identify each new line and set the info to a variable.
Basically I need to take the textfile info and add to the following variables
$Name
$Age
$Address
I thought of using an Array but since I'm mixing strings and numbers, I can't use a String array.
Since I'm using Line per line there is no delimiter.
** Updated info **
I used name, age and address as example variables, and got some of the answers kind of working but I still can't get it completely working, so I should post the whole code . . .
I'm open to code cleanup as well (I'm really new to Java)
The answers given I kind of got to work, except the reader is separating the variables by spaces and in a situation like name and address both have spaces in them, the space delimiter isn't giving me the results I need.
Here is the textfile contents:
Ray Wade
200
American Foundation for Children with AIDS
Tom Hardy
125.50
American Red Cross
As you can see I call the LoadTextFile(); within the CreateTables() function
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.sql.*;
import javax.sql.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class Charity extends JFrame
{
JButton btnCalc = new JButton("Donate"), btnLoad = new JButton("Load File"), btnExit = new JButton("Exit");
JLabel name, amount, intro = new JLabel("Would You Like to Donate to a Charity Today? It Only Takes a Few Moments"), message1 = new JLabel(""), message2 = new JLabel("");
JTextField textName, textAmount;
// Create String Array to list charities in the combobox
String[] charities = { "Choose a Charity or Enter a New Charity",
"American Foundation for Children with AIDS",
"American Red Cross",
"Breast Cancer Research Foundation",
"Livestrong *Formerly Lance Armstrong Foundation*",
"Michael J. Fox Foundation for Parkinson's Research" };
JComboBox charityList = new JComboBox(charities);
String file ="Charity.txt";
// Variables used later
double dAmount;
String Charity = null;
int debug = 0; // change to 1 to turn debug mode on
// Variables initialized for Database Stuff
Object[][] databaseInfo;
Object[] columns = {"name", "charity", "amount"};
Connection conn = null;
ResultSet rows;
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/";
String DBname = "charity";
String DBusername = "root";
String DBpass = "password";
// Variables and Class for TableModel
DefaultTableModel dTableModel = new DefaultTableModel(databaseInfo, columns){
public Class getColumnClass(int column) {
Class returnValue;
// Verifying that the column exists (index > 0 && index < number of columns
if ((column >= 0) && (column < getColumnCount())) {
returnValue = getValueAt(0, column).getClass();
} else {
// Returns the class for the item in the column
returnValue = Object.class;
}
return returnValue;
}
};
/**
Sets the title, size and layout of the JFrame.<!-- -->Also calls the methods to setup the panels.
*/
public Charity()
{
super("Donations to Charities"); // Title of frame
setLayout(new FlowLayout()); // Declare layout of frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Default close
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); // Get screen size
this.setResizable( false ); // turn off frame resize
this.setSize(600, dim.height-100); // set size of frame
CreatePanels();
GetAction(); // Call ActionListeners
CreateDatabase();
}
public void CreatePanels()
{
SetupCharityGroup(); // Call method to setup charity list panel
SetupDataPanel(); // Call method to setup data collection panel
SetupDisplayTable();
setVisible(true); // Make frame visible
}
/**
Method to setup the display panel containing a JTable that will show the information read from the database.
*/
private void SetupDisplayTable()
{
JTable table = new JTable(dTableModel); // Create a JTable using the custom DefaultTableModel
table.setFont(new Font("Serif", Font.PLAIN, 16)); // Increase the font size for the cells in the table
table.setRowHeight(table.getRowHeight()+5); // Increase the size of the cells to allow for bigger fonts
table.setAutoCreateRowSorter(true); // Allows the user to sort the data
// right justify amount column
TableColumn tc = table.getColumn("amount");
RightTableCellRenderer rightRenderer = new RightTableCellRenderer();
tc.setCellRenderer(rightRenderer);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // Disable auto resizing
// Set the width for the columns
TableColumn col1 = table.getColumnModel().getColumn(0);
col1.setPreferredWidth(200);
TableColumn col2 = table.getColumnModel().getColumn(1);
col2.setPreferredWidth(275);
TableColumn col3 = table.getColumnModel().getColumn(2);
col3.setPreferredWidth(75);
// Put the table in a scrollpane and add scrollpane to the frame
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setPreferredSize(new Dimension(552, 400));
this.add(scrollPane, BorderLayout.CENTER);
}
/**
Method to setup the data panel containing textFields, Labels, and buttons.
*/
private void SetupDataPanel()
{
JPanel pan = new JPanel();
GridLayout grid = new GridLayout(0, 1, 5, 5);
pan.setLayout(grid);
// Setup TextFields and Labels for name of person donating
// and add them to the panel
name = new JLabel("Name");
textName = new JTextField("", 16);
textName.setHorizontalAlignment(JTextField.RIGHT);
pan.add(name);
pan.add(textName);
// Setup TextFields and Labels for amount being donated
// and add them to the panel
amount = new JLabel("Donation Amount");
textAmount = new JTextField("", 4);
textAmount.setHorizontalAlignment(JTextField.RIGHT);
pan.add(amount);
pan.add(textAmount);
// add buttons and message labels to panel
pan.add(intro);
pan.add(btnCalc);
pan.add(btnLoad);
pan.add(btnExit);
pan.add(message1);
pan.add(message2);
this.add(pan);
}
/**
Method to setup the charity panel with a border containing an editable combobox filled with a list of charities.
*/
private void SetupCharityGroup()
{
JPanel Boxpan=new JPanel();
Boxpan.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Charities"));
this.add(Boxpan);
charityList.setEditable(true);
Boxpan.add(charityList);
}
/**
Add ActionHandlers to interactive elements.
*/
private void GetAction()
{
ActionHandler handler = new ActionHandler();
btnLoad.addActionListener(handler);
btnCalc.addActionListener(handler);
btnExit.addActionListener(handler);
charityList.addActionListener( handler );
}
/**
Method to make ActionHandlers into ActionListeners.
*/
private class ActionHandler implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
String incmd = evt.getActionCommand();
if (incmd.equals("Donate")) // If Donate button is pressed
if (textName.getText().isEmpty())
{
message1.setText("<html><font color='red'>Invalid Donation</font>");
message2.setText("<html><font color='red'>Error: Name of Donor missing!<font>");
} else
CheckDonate();
else if (incmd.equals("Load File")) // If Load File button is pressed
DatabaseLoad();
else if (incmd.equals("Exit")) // If Exit button is pressed
System.exit(0);
}
}
/**
Method to check if charity is selected in the combobox.<!-- -->If a charity is selected, call CharitySelected method, otherwise send error message to Frame.
*/
private void CheckCharity()
{
Object selectedCharity = charityList.getSelectedItem();
if (charityList.getSelectedIndex() == 0) // if charity is not selected
{
message1.setText("<html><font color='red'>Invalid Donation</font>");
message2.setText("<html><font color='red'>Error: No Charity Selected!<font>");
} else CharityIsSelected();
}
/**
If charity is selected, set the selected value to "Charity" variable and call method to thank donator.
*/
private void CharityIsSelected()
{
Object selectedCharity = charityList.getSelectedItem();
Charity = selectedCharity.toString(); // selectedCharity Object converted to String
ThankYou();
}
/**
Thank the donator and call the databseAdd method.
*/
private void ThankYou()
{
message1.setText("Thank You! "+textName.getText());
message2.setText(" $"+textAmount.getText()+" Will be donated to "+Charity);
DatabaseAdd();
}
/**
Method that will check that donation amount is a number in a range between 1 and 1000000000.
*/
private void CheckDonate()
{ try
{
dAmount = Double.parseDouble(textAmount.getText());
if(dAmount <= 0.0 || dAmount > 1000000000 )
{
message1.setText("<html><font color='red'>Invalid Donation</font>");
message2.setText("<html><font color='red'>Amount invalid</font>");
} else CheckCharity();
} catch (NumberFormatException ex) {
// Executes if the data entered is not a number
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("");
} else
{
message1.setText("<html><font color='red'>Invalid Donation</font>");
message2.setText("<html><font color='red'>Amount Not Recognized</font>");
}
}
}
public void DBConnection()
{ try
{
// The driver allows you to query the database with Java
// forName dynamically loads the class for you
Class.forName(driver);
// DriverManager is used to handle a set of JDBC drivers
// getConnection establishes a connection to the database
// You must also pass the userid and password for the database
conn = DriverManager.getConnection (url, DBusername, DBpass);
} catch (SQLException ex) {
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("Error: "+ex.getErrorCode());
} else
message1.setText("Database Error: contact admin");
message2.setText("");
} catch (ClassNotFoundException ex) {
// Executes if the driver can't be found
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("");
} else
message1.setText("Driver Error: contact admin");
message2.setText("");
}
}
/**
Method to add the entered information to the database.<!-- -->Once the information is added to the database, clear the form fields.
*/
private void DatabaseAdd()
{ try
{
url = url+DBname;
DBConnection();
// Statement objects executes a SQL query
// createStatement returns a Statement object
Statement s = conn.createStatement();
// Prepare the query and values to be inserted into the database
String str="INSERT INTO donations(name,charity,amount) VALUES (?,?,?)";
java.sql.PreparedStatement statement = conn.prepareStatement(str);
statement.setString(1,textName.getText());
statement.setString(2,Charity);
statement.setDouble(3,dAmount);
statement.executeUpdate();
// Reset form after saved to database
textName.setText("");
textAmount.setText("");
charityList.setSelectedIndex(0);
s.close();
DatabaseLoad(); // Call the Database Info
} catch (SQLException ex) {
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("Error: "+ex.getErrorCode());
} else
message1.setText("Database Error: contact admin");
message2.setText("");
}
}
/**
Method will load the database information and display it in Frame in a JTable.
*/
private void DatabaseLoad()
{ try
{
url = url+DBname;
DBConnection();
// Statement objects executes a SQL query
// createStatement returns a Statement object
Statement s = conn.createStatement();
// This is the query I'm sending to the database
String selectStuff = "SELECT `name`, `charity`, `amount` FROM `"+DBname+"`.`donations` ";
// A ResultSet contains a table of data representing the
// results of the query. It can not be changed and can
// only be read in one direction
rows = s.executeQuery(selectStuff);
// Set the table RowCount to 0
dTableModel.setRowCount(0);
// Temporarily holds the row results
Object[] tempRow;
// next is used to iterate through the results of a query
while(rows.next())
{
// Gets the column values based on class type expected
tempRow = new Object[]{rows.getString(1), rows.getString(2), rows.getDouble(3) };
dTableModel.addRow(tempRow); // Adds the row of data to the end of the model
}
// Successfully loaded, message the user
message1.setText("<html><font color='red'>Database Info Loaded</font>");
message2.setText("");
s.close();
} catch (SQLException ex) {
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("Error: "+ex.getErrorCode());
} else
message1.setText("Database Error: contact admin");
message2.setText("");
}
}
/**
Method will create the database if it does not exist.
*/
private void CreateDatabase()
{ try
{
DBConnection();
// Statement objects executes a SQL query
// createStatement returns a Statement object
Statement s = conn.createStatement();
String dbCreate = "CREATE DATABASE "+DBname;
s.executeUpdate(dbCreate);
s.close();
} catch(SQLException ex){
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("Error: "+ex.getErrorCode());
}
} catch(Exception ex){
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("");
}
}
CreateTables();
}
/**
Method will create the table needed in the database.
*/
private void CreateTables()
{ try
{
DBConnection();
// Statement objects executes a SQL query
// createStatement returns a Statement object
Statement s = conn.createStatement();
String tableCreate = "create table "+DBname+".donations " + "(`name` varchar(200), " + "`charity` varchar(200), " + "amount double)";
s.executeUpdate(tableCreate);
// After creating the tables
// Load the information from the textfile
LoadTextFile();
s.close();
} catch(SQLException ex){
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("Error: "+ex.getErrorCode());
}
} catch(Exception ex){
// debug:
if (debug == 1)
{
message1.setText("Error: "+ex.getMessage());
message2.setText("");
}
}
}
public void LoadTextFile()
{
}
// To change justification to the right
class RightTableCellRenderer extends DefaultTableCellRenderer {
public RightTableCellRenderer() {
setHorizontalAlignment(JLabel.RIGHT);
}
}
// Main method calls the constructor
public static void main(String[] args)
{
new Charity();
}
}
Following code snippet will solve your problem.
public class Test {
public static void main( String[] args ) throws Exception
{
HashMap<String, Person> personMap = new HashMap<String, Person>();
try
{
BufferedReader in = new BufferedReader( new FileReader( "File Path" ) );
String str;
Person person = new Person();
int count = 0;
String key = "";
while( ( str = in.readLine() ) != null )
{
if ( null != str && str.trim().length() == 0 )
{
personMap.put( key, person );
count = -1;
person = new Person();
}
else {
String arr[] = str.split( " " );
key = arr[0];
if (count == 0) {
person.setName( arr[1] );
}
else if (count == 1) {
person.setAge( arr[1] );
}
else if (count == 2) {
person.setAddress( arr[1] );
}
}
count ++;
}
personMap.put( key, person );
in.close();
}
catch( IOException e )
{
System.out.println( "Exception" + e.getMessage() );
}
}
}
public class Person
{
private String name = null;
private String age = null;
private String Address = null;
public String getName()
{
return name;
}
public void setName( String name )
{
this.name = name;
}
public String getAge()
{
return age;
}
public void setAge( String age )
{
this.age = age;
}
public String getAddress()
{
return Address;
}
public void setAddress( String address )
{
Address = address;
}
}
I hope it helps
Use BufferedReader to read one line at a time, extract the required info from that line and assign it to the variables. In case you want to hold it in the memory, use a POJO with those 3 properties.
You may use regex to split the line and get the required value(s).
I wrote a set of functions that does something similar. I use a bufferedReader like the other user suggested.
public ArrayList<String> readFileToMemory(String filepath)
{
BufferedReader br = null;
String currentLine = null;
ArrayList<String> fileContents = new ArrayList<String>();
try
{
br = new BufferedReader(new FileReader(filepath));
while((currentLine = br.readLine()) != null)
{
//fileContents.add(br.readLine());
fileContents.add(currentLine);
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
br.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
return fileContents;
}
This will just read in the each line of a file as a separate entry in a list. Just take the entries and do what you need.
If you're only doing this once, just do 3 replaces in notepad ++
Replace \r\n\r\n with "|||"
replace \r\n with ","
replace ||| with \r\n
then you've got a regular .csv file.

Categories

Resources