Question Now once the data is fetched from the database and shown in the JTable object "table" embedded in the scrollPane, how do we create a print job that makes it possible to print the displayed table as such in A3 sized paper ?
My code to fetch the data from the database is shown below:
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost/newb","root","pass");
Statement stat=con.createStatement();
ResultSet res=stat.executeQuery("select * from table where name = '"+name+"'");
ResultSetMetaData rsmd = res.getMetaData();
int colcount = rsmd.getColumnCount();
Vector columns = new Vector(colcount);
for(int i=3; i<=colcount; i++)
{
columns.add(rsmd.getColumnName(i));
}
Vector data = new Vector();
Vector row;
// Store row data
while(res.next())
{
row = new Vector(colcount);
for(int i=3; i<=colcount; i++)
{
row.add(res.getString(i));
}
data.add(row);
}
table = new JTable(data, columns);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
scrollPane.setViewportView(table);
}
catch(Exception ex)
{
System.out.println(ex);
}
I am using vector class to fetch the data from the table. How do we print the data shown in the displayed table to a paper?
just use JTable.print() method. here is an article about sending JTable into printer and another one with more parameters
You obviously didn't read the links provided in your previous question.
From the Printing section of How to use Tables
Printing
JTable provides a simple API for printing tables. The easiest way to
print out a table is to invoke JTable.print with no arguments:
try {
if (! table.print()) {
System.err.println("User cancelled printing");
}
} catch (java.awt.print.PrinterException e) {
System.err.format("Cannot print %s%n", e.getMessage());
}
Invoking print on a normal Swing application brings up a standard printing
dialog box. (On a headless application, the table is simply printed.)
The return value indicates whether the user went ahead with the print
job or cancelled it. JTable.print can throw
java.awt.print.PrinterException, which is a checked exception; that's
why the above example uses a try ... catch.
JTable provides several overloads of print with various options. The
following code from TablePrintDemo.java shows how to define a page
header:
MessageFormat header = new MessageFormat("Page {0,number,integer}");
try {
table.print(JTable.PrintMode.FIT_WIDTH, header, null);
} catch (java.awt.print.PrinterException e) {
System.err.format("Cannot print %s%n", e.getMessage());
}
For more sophisticated printing applications, use JTable.getPrintable to obtain
a Printable object for the table. For more on Printable, refer to the
Printing lesson in the 2D Graphics trail.
i hope help you with this code try it its for How to print JTable in Java netbeans
private void btn_printActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
MessageFormat header = new MessageFormat("Print Report");
MessageFormat footer = new MessageFormat("Page{0,number,integer}");
try {
table_employee.print(JTable.PrintMode.FIT_WIDTH, header, footer);
} catch (java.awt.print.PrinterAbortException e) {
} catch (PrinterException ex) {
Logger.getLogger(employee_info.class.getName()).log(Level.SEVERE, null, ex);
}
}
Related
I am trying to populate a table within a docx file with data from java objects. More precisely each row represents an Object and my pattern starts with one row. I want to find out how can I introduce a new row in case I have more than one objects in my list. See example below:
Docx table looks like this:
And I successfully realized the mapping with the fields but for ONLY one object. How can i introduce another row (from Java) to make room for another object ? For this implementation I am using org.apache.poi.xwpf.usermodel.XWPFDocument;
public class DocMagic {
public static XWPFDocument replaceTextFor(XWPFDocument doc, String findText, String replaceText) {
replaceTextFor(doc.getParagraphs(),findText,replaceText);
doc.getTables().forEach(p -> {
p.getRows().forEach(row -> {
row.getTableCells().forEach(cell -> {
replaceTextFor(cell.getParagraphs(), findText, replaceText);
});
});
});
return doc;
}
private static void replaceTextFor(List<XWPFParagraph> paragraphs, String findText, String replaceText) {
paragraphs.forEach(p -> {
p.getRuns().forEach(run -> {
String text = run.text();
if (text.contains(findText)) {
run.setText(text.replace(findText, replaceText), 0);
}
});
});
}
public static void saveWord(String filePath, XWPFDocument doc) throws FileNotFoundException, IOException {
FileOutputStream out = null;
try {
out = new FileOutputStream(filePath);
doc.write(out);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
}
}
EDIT: using addNewTableCell().setText() places the values on the right side of the table
Normally you use below steps to add row in a table,
XWPFTableRow row =tbl.createRow();
row.addNewTableCell().setText("whatever you want");
tbl.addRow(row, y);
But in your case seems you want to add rows on the fly while you are iterating the docx table together with your Java list of object,
In Java your are not safe or able to change the collection while looping it,
so you might need to do it in 2 steps,
you need to expand/add rows first to the docx table before you populate it,
by firstly calculate how many objects you have in your java list.
when the table rows are already added accordingly, you could iterate and populate them
I want to Print JTABLE and A value from Text Field. Its like products detail and there Bill Print.
Here is the image.
Required Print is Table + Total Amount,
But so far i got JTable.print() only print table. is there any way to add other values at end as total ??
Here is the code of printing jtable.
MessageFormat header = new MessageFormat("Purchases Bill {0,number,integer}");
try {
table.print(JTable.PrintMode.FIT_WIDTH, header, null);
} catch (java.awt.print.PrinterException e) {
System.err.format("Cannot print %s%n", e.getMessage());
}
Use jtextfield1.print(); I think it will work. It will only print the specified textfield.
This Code is in a While Loop, and each time I run a new Query it will go through this block after I have chosen what to filter it by, the problem is when I run it a second time and click on a cell in my table it will revert to cells in my previous table/query. I attached an image to show what I mean(I need 10 reputation for that so nevermind on the picture), I filtered the table by procsessState = -1 and when I clicked on some cells it reverted to what the previous table had. Help would be greatly appreciated. The program is around 1000 lines long and I did a terrible job of splitting it into different classes So I just posted where I am almost certain the issue arises.
I declared
final String columnNamesForTable[] = {"Error Message", "ID", "Locked By", "Message Id", "Process State",
"Row Date", "Sender", "Sent Date", "Subject" };
At The top, then I have this a bit later on.
else if (checkBoxCounter != 0)
{
DefaultTableModel tableModel = new DefaultTableModel(columnNamesForTable, 0);
tableModel.fireTableDataChanged();
try
{
Connection conn = DatabaseConnection.getConnection();
System.out.println("Connected");
PreparedStatement statement = conn.prepareStatement(sb.toString(),
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
// Change CONCUR_READ_ONLY to CONCUR_UPDATABLE
ResultSet resultSet = statement.executeQuery();
int errorMessageIndex = resultSet.findColumn("ErrorMessage");
int idIndex = resultSet.findColumn("Id");
int lockedByIndex = resultSet.findColumn("LockedBy");
int messageIdIndex = resultSet.findColumn("MessageId");
int processStateIndex = resultSet.findColumn("ProcessState");
int rowDateIndex = resultSet.findColumn("RowDate");
int senderIndex = resultSet.findColumn("Sender");
int sentDateIndex = resultSet.findColumn("SentDate");
int subjectIndex = resultSet.findColumn("Subject");
while (resultSet.next()) {
Object[] rowsForTable = { resultSet.getString(errorMessageIndex),
resultSet.getString(idIndex), resultSet.getString(lockedByIndex),
resultSet.getString(messageIdIndex), resultSet.getString(processStateIndex),
resultSet.getString(rowDateIndex), resultSet.getString(senderIndex),
resultSet.getString(sentDateIndex), resultSet.getString(subjectIndex)};
tableModel.addRow(rowsForTable);
}
resultSet.close();
statement.close();
conn.close();
filterFrame.setVisible(false);
JTable resultsTable = new JTable(tableModel);
JScrollPane pane = new JScrollPane(resultsTable);
displayPnl.add(pane);
pack();
resultsTable.repaint();
isDone= true;
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Database error");
ex.printStackTrace();
isDone = true;
} catch (ClassNotFoundException ex) {
JOptionPane.showMessageDialog(null, "Error loading database driver");
ex.printStackTrace();
isDone = true;
}
}
This Code is in a While Loop
Why would it be in a while loop. Swing is event driven. Code should only be executed when the uses generates some kind of event like clicking on a button, typing text, editing a cell.
I have chosen what to filter it by,
Don't create a whole new table and scroll pane. Just update the TableModel of the existing JTable.
pack();
Why would you pack the frame. The query could have 100's of rows of data. Pick a reasonable size for the table when the frame is created and there is no need to use pack() or repaint(). When you invoke the setModel(...) method of the JTable to replace the current model the table will be repainted automatically.
So all the code you need should be:
//filterFrame.setVisible(false);
//JTable resultsTable = new JTable(tableModel);
//JScrollPane pane = new JScrollPane(resultsTable);
//displayPnl.add(pane);
//pack();
//resultsTable.repaint();
existingTable.setModel( tableModel );
I cant comment I do not have enough reputation.
You fire tabledatachanged before changing data.
TableDataChanged does not always properly update rows , it seems better to fire update rows.
If your table is editable , if you clicked the table you need to release the editor.
I know how to populate jtable and i had prepared the code for the above which works fine. But the problem is that it is working in another project but bot in my current project. The code for both the project is same. Here is the code... purchaswtab is the table name which has been already created using swing palette. And this function is executed in the event of the exit button of the Item Master.
the array elements of an array ap are defined as i have to fetch them from the given position from the resultset.
public void populatetable(ItemMaster imm)
{
imm.dispose();
String t[][]=new String [30][10];
int[] ap={19,1,2,4,18,16,17};
Object[] h1=new Object[7];
String a1,a2;
int j=0,i=1;
int len=0;
try
{
st=fun.connect1();
String query="select * from Temp_Purchase";
ResultSet rs=st.executeQuery(query);
ResultSetMetaData rsmd=rs.getMetaData();
while(rs.next())
{
int k=0;
for(i=1;i<=7;i++,k++ )
{
t[j][i-1]=rs.getString(ap[k]);
System.out.println(t[j][i-1]);
}
j++;
len++;
}
fun.close();
}
catch(Exception e)
{
fun.close();
System.out.println("Exception:"+e);
}
DefaultTableModel de=(DefaultTableModel)purchaseTab.getModel();
purchaseTab=new JTable(de);
//Code for filling data into table
for(i=0;i<len;i++)
{
for(j=1;j<=7;j++)
{
h1[j-1]=t[i][j-1];
}
if(h1[0]=="0")
{
h1[0]=Boolean.FALSE;
}
de.insertRow(i,h1);
}
//jsp.setViewportView(Table);
}
replace evetything inside while(rs.next()) to de.addRow(new Object[..., ..., ...]);
you have to declare DefaultTableModel de as local variable, initialized before fun is called
then to pass DefaultTableModel de to JTable, e.g. myTable(de); or myTable.setModel(de)
use Object[] instead of limitations for String[], then you can to store various data type in DefaultTableModel
From #mKorbel's answer
Create and add a DefaultTableModel like:
DefaultTableModel model=new DefaultTableModel(data,header);
JTable table = new JTable(model);
Here data is double vector and header is single vector.
data = get(field);
Object[] d={data.get(i).get(0),data.get(i).get(1),data.get(i).get(2)};
model.addRow(d);
Get data from database
get(field){
//Your Database connection
//Get data into vector
//return vector
}
I have the following method which creates a JTable then prints it out by its appearing as a rectangle no the page with the header and footer.
public void printModules(){
MessageFormat header = new MessageFormat("Modules " + new Date());
MessageFormat footer = new MessageFormat("Created by Assignments Database");
try {
JTable jtModules = new JTable(new ModulesTableModel(Controller.getInstance().getModules()));
jtModules.setShowHorizontalLines(true);
jtModules.setShowVerticalLines(true);
jtModules.setShowGrid(true);
boolean complete = jtModules.print(JTable.PrintMode.NORMAL, header, footer, true, null, false, null);
if(complete){
System.out.println("Printed");
} else{
System.out.println("Printing Cancelled");
}
} catch (PrinterException e) {
e.printStackTrace();
}
}
What else is wrong? There is data in the table as one that is created from the same data is showing in one of the panels.
In my abstract table model I have implemented the following methods:
Constructor
getRowCount
getColumnCount
getValueAt
getColumnNames
Is there any other methods that need to be created?
JTable has very reduced support for printing, there are some descriptions about printing in the tutorials about JTable (inc. code example) and Printing
You need to display the table in order to print it, so add it to a JFrame, then frame.setVisible(true); then frame.setVisible(false);
This will make it print.