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.
Related
I am creating a GUI that will allow the user to input Lake information for the state of Florida and then has the ability to display that lake information. I want the display information to be in a JOptionPane.showMessageDialog that has the ability to scroll through the ArrayList of all the lake names. I am able to add the lakes into the ArrayList but they will not display in my JOptionPane and it is blank. I know it is reading something in the ArrayList since it is opening that window. Here is the code below in snippets as the whole thing would be cra.
public static ArrayList<Lakes> lake = new ArrayList<Lakes>();
private JTextArea textAreaDisplay;
private JScrollPane spDisplay;
// this is called in my initComponent method to create both
textAreaDisplay = new JTextArea();
for (Object obj : lake)
{
textAreaDisplay.append(obj.toString() + " ");
}
spDisplay = new JScrollPane(textAreaDisplay);
textAreaDisplay.setLineWrap(true);
textAreaDisplay.setWrapStyleWord(true);
spDisplay.setPreferredSize(new Dimension(500, 500));
// this is called in my createEvents method. After creating lakes in the database
// it will display the else statement but it is empty
btnDisplayLake.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try
{
if (lake.size() == 0)
{
JOptionPane.showMessageDialog(null, "No Lakes in database!");
}
else
JOptionPane.showMessageDialog(null, spDisplay, "Display Lakes", JOptionPane.YES_NO_OPTION);
}
catch (Exception e1)
{
}
}
});
Thank you for any help you can provide. I have been racking my brain for a few days on this. Been able to get other stuff accomplished but coming back to this issue.
Some obvious issues:
textAreaDisplay = new JTextArea();
A JTextArea should be created with code like:
textAreaDisplay = new JTextArea(5, 20);
By specifying the row/column the text area will be able to calculate its own preferred size. Scrollbars should appear when the preferred size of the text area is greater than the size of the scroll pane.
spDisplay.setPreferredSize(new Dimension(500, 500));
Don't use setPreferredSize(). The scroll area will calculate its preferred size based on the preferred size of the text area.
textAreaDisplay.append(obj.toString() + " ");
I would think you want each Lake to show on a different line, so I would append "\n" instead of the space.
I was setting textAreaDisplay before anything was entered into the ArrayList and it would not run again after anything was entered. I moved the for loop down and into the actionPerformed event and works well now.
btnDisplayLake.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try
{
for (Object obj : lake)
{
textAreaDisplay.append(obj.toString() + "\n");
}
if (lake.size() == 0)
{
JOptionPane.showMessageDialog(null, "No Lakes in database!");
}
else
JOptionPane.showMessageDialog(null, spDisplay, "Display Lakes", JOptionPane.YES_NO_OPTION);
}
catch (Exception e1)
{
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);
}
}
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.
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.
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.