How to print out specific rows/columns of a JTable? - java

I am able to print a full JTable, but actually I would like more to print just a specific part of a JTable, for example from Row 10 to Row 50 and Column 70 to Column 150.
How to do it ?

I've faced this problem too. Solved by hiding columns before printing and restoring columns after printing:
// get column num from settings
int num = gridSettings.getColumnsOnPage();// first <num> columns of the table will be printed
final TableColumnModel model = table.getColumnModel();
// list of removed columns. After printing we add them back
final List<TableColumn> removed = new ArrayList<TableColumn>();
int columnCount = model.getColumnCount();
// hiding columns which are not used for printing
for(int i = num; i < columnCount; ++i){
TableColumn col = model.getColumn(num);
removed.add(col);
model.removeColumn(col);
}
// printing after GUI will be updated
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// table printing
try {
table.print(PrintMode.FIT_WIDTH, null, null, true, hpset, true); // here can be your printing
} catch (PrinterException e) {
e.printStackTrace();
}
// columns restoring
for(TableColumn col : removed){
model.addColumn(col);
}
}
});
For printing your specific part of a JTable, just change a little bit this code.

Get cell bounds for the selected fragment and calculate desired region (Rectangle), define clip region to paint only desired region, in the printable use Graphics's translate() method to shift the rendering.

Related

JTable Duplicates Columns when "Hiding" and "Showing" them

I am currently using a JTable to display a few patient details. I have a JCheckBox, that when ticked adds a new column to the table and adds the data to the new column. When it is unticked, it should remove the column, sort of like adding extra filters to the table. However, when I tick the box again after unticking it, it duplicates the columns in the table.
I tried to use the fireTableStructureChanged() method, but it would never update the table and so the columns stay there even if the checkbox was unticked. But if I remove it, then when I untick the the checkbox it works, but then the duplication problem comes back. I pasted my actionPerformed() method for when the checkbox is ticked. The first image is of my table before I click my Checkbox. The second is when I click the Checkbox and the column is added. Lastly the third is when I untick the checkbox and tick again. Any help will be much appreciated.
#Override
public void actionPerformed(ActionEvent e)
{
if (gui.getChkCholesterol().isSelected() == true)
{
try {
gui.getRightTableModel().addColumn("Cholesterol");
newColumnIndeces.put("2093-3",gui.getRightTable().getColumnCount()-1);
gui.getRightTableModel().addColumn("Cholesterol Effective Date/Time");
newColumnIndeces.put("2093-3e",gui.getRightTable().getColumnCount()-1);
if(gui.getRightTable().getRowCount()>0)
{
int columnNumberValue = newColumnIndeces.get("2093-3");
int columnNumberDate = newColumnIndeces.get("2093-3e");
for (int i = 0; i<gui.getRightTable().getRowCount(); i++)
{
String value = op.getPatientObservationValue(gui.getRightTable().getValueAt(i,0).toString(),"2093-3");
String date = op.getPatientObservationEffectiveDate(gui.getRightTable().getValueAt(i,0).toString(),"2093-3");
gui.getRightTableModel().setValueAt(value, i, columnNumberValue);
gui.getRightTableModel().setValueAt(date, i, columnNumberDate);
}
}
} catch (ParseException parseException) {
parseException.printStackTrace();
}
setCellColourForTable();
timer.schedule(new RefreshTable(), 0, seconds);
}
else
{
gui.getRightTable().removeColumn(gui.getRightTable().getColumnModel().getColumn(newColumnIndeces.get("2093-3")));
gui.getRightTable().removeColumn(gui.getRightTable().getColumnModel().getColumn(newColumnIndeces.get("2093-3e")-1));
newColumnIndeces.remove("2093-3");
newColumnIndeces.remove("2093-3e");
timer.cancel();
timer = new Timer();
}
gui.getRightTableModel().fireTableStructureChanged();
}
You add a column to the model by using:
gui.getRightTableModel().addColumn("Cholesterol");
This will notify the view that the data has changed and the table will also be updated.
However, you remove the column from the table using:
gui.getRightTable().removeColumn(…);
This only removes the column from the "table view". The column has not been removed from the DefaultTableModel. So the next time you add a column it just gets added to the end of the DefaultTableModel.
So the solution is to remove the column from the DefaultTableModel, not the table.
Unfortunately there is no removeColumn(…) method.
However because your requirement is to only add/remove columns from the end of the DefaultTableModel you can use:
model.setColumnCount(model.getColumnCount() - 2);
which will effectively remove the last two columns from the model.
The other option is to not keep adding columns to the DefaultTableModel, but instead you can just add/remove TableColumns from the TableColumnModel directly. So this would mean the data for the Cholestoral column would always be in the model, but the view would just not display the columns.
So instead of using the model.addColumn(…) you would use the table.addColumn(…) method.

Is it possible jtable row in optionDialog box

I have a jtable.
Some of the cells contain very long strings and trying to scroll left and right through it is difficult. My question is whether it is possible to show a row from a JTable in a pop-up eg showDialog type box (ie where the selected row is organised as a column).
Even a link to a tutorial would do.
I have scoured the internet but I don't think I'm really using the correct keywords as I get a lot of right-click options.
If this is not possible are there any other suggestions for how to do this?
As shown here, the JOptionPane factory methods will display the Object passed in the message parameter. If that message is a one column JTable, you can recycle any custom renderers and editors that were applied to the original table.
In outline,
Add a ListSelectionListener to your table and get the selectedRow.
Iterate through the table's model and construct a newModel whose rows are the columns of the selectedRow.
Create a JTable newTable = new JTable(newModel).
Apply any non-default renderers and editors.
Pass a new JScrollPane(newTable) as the message parameter to your chosen JOptionPane method.
Starting from this example, the following listener displays the dialog pictured.
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
int selectedRow = table.convertRowIndexToModel(table.getSelectedRow());
if (selectedRow > -1) {
DefaultTableModel newModel = new DefaultTableModel();
String rowName = "Row: " + selectedRow;
newModel.setColumnIdentifiers(new Object[]{rowName});
for (int i = 0; i < model.getColumnCount(); i++) {
newModel.addRow(new Object[]{model.getValueAt(selectedRow, i)});
}
JTable newTable = new JTable(newModel) {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(140, 240);
}
};
// Apply any custom renderers and editors
JOptionPane.showMessageDialog(f, new JScrollPane(newTable),
rowName, JOptionPane.PLAIN_MESSAGE);
}
}
});
I want to show all the values in the row, each in their cel, organised vertically- that's what I meant by 'in a column'.
That should be in the question, not in the comment.
There is no default functionality for this but you can do it yourself.
You could create a JPanel (maybe using a GridBagLayout), with two labels in a row to represent the data in a column of the selected row of the table.
For the data in the first label you would use the getColumnName(...) method of the TableModel.
For the data in the second label you would use the getValueAt(...) method of the TableModel.
Another option is to simply display a tool tip for the cell. See the section from the Swing tutorial on Specifying ToolTips For Cells for more information.
You may use the following ListSelectionListener:
final JTable dialogTable =new JTable();
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent event) {
int selectedRow = table.getSelectedRow();
if (selectedRow > -1) {
int columnCount = table.getModel().getColumnCount();
Object[] column = new Object[]{"Row "+(selectedRow+1)};
Object[][] data = new Object[columnCount][1];
for (int i = 0; i < columnCount; i++) {
Object obj = table.getModel().getValueAt(selectedRow, i);
data[i][0] = obj;
}
dialogTable.setModel(new DefaultTableModel(data, column));
JOptionPane.showMessageDialog(null, new JScrollPane(dialogTable));
}
}
});
This is going to show a message dialog which contains a JTable with data that is derived from the selected row. Hope this helps you.

How can i clear the all contents of the cell data in every row in my tableview in JAVA FX

I am finding hard to clear the table contents in my table. I have tried this code.
for ( int i = 0; i<resultTable.getItems().size(); i++) {
resultTable.getItems().clear();
}
To clarify my question, the problem I am having is that i want to delete the values in my table. This was the first code i used;
public void removeRow(){
allFiles = table.getItems(); fileSelected = table.getSelectionModel().getSelectedItems();
fileSelected.forEach(allFiles :: remove);
}
But it only removes a particular selected row. I want to clear all the rows and leave the table empty at once, without having to select any row. I tried to use this code;
public void removeAllRows(){
for ( int i = 0; i<resultTable.getItems().size(); i++) {
resultTable.getItems().clear();
}
}
but it does not clear all the rows in the table
My plan is to use this method as an action for a button.
e.g
Button btn = new ("Clear Table");
btn..setOnAction(e->{removeAllRows();});
When this button is clicked, it should delete all rows in the table at once.
tableView.getItems().clear()
Will do the trick
Try using the following: Name "tableView" to whatever your FXMLtable is called
for ( int i = 0; i<tableView.getItems().size(); i++) {
tableView.getItems().clear();
}

How to use hidden column data of jTable in tooltip

I am trying to display the data of hidden column as tooltip. Hiding is working perfectly using the following code:
JTable table = new JTable(model){
//Implement table cell tool tips.
public String getToolTipText(MouseEvent e) {
String tip = null;
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
int realColumnIndex = convertColumnIndexToModel(colIndex);
try {
tip = getValueAt(rowIndex, 8).toString();
} catch (RuntimeException e1) {
//catch null pointer exception if mouse is over an empty line
}
return tip;
}
};
TableColumnModel tcm = table.getColumnModel();
TableColumn tc;
for(int i = 1; i <= 7; i++){
tc = tcm.getColumn(8);
tcm.removeColumn(tc);
}
But the tooltip is not showing the data of hidden column (getValue function is not returning value). So do hiding the column delete the data as well ?
You do not need to for loop as you do not use the i variable ;-)
The removeColumn on the JTable does not remove the data from the model, as clearly stated in the javadoc
Removes aColumn from this JTable's array of columns. Note: this method does not remove the column of data from the model; it just removes the TableColumn that was responsible for displaying it.
There is no mention in the javadoc for the same method on the TableColumnModel, but I would assume it works the same way, but you can always give it a try to call it on the JTable instead
The real problem in your code is the use of getValueAt, which uses the row and column index of the table, and not of the model
Note: The column is specified in the table view's display order, and not in the TableModel's column order. This is an important distinction because as the user rearranges the columns in the table, the column at a given index in the view will change. Meanwhile the user's actions never affect the model's column ordering.
And since you removed that column, it simply does not exists for the table. Call the getValue method on the model instead, and do not forget to convert the row index

Printing user specified column from JTable

I have an application, and I would like to print a JTable, but since it has many columns, I would like user to select/limit which columns to print so it can fit in regular printer paper.
I'm using JTable.print() function to print. (http://java.sun.com/docs/books/tutorial/uiswing/misc/printtable.html)
Right now, my solution, is to create another JTable with the columns that user selected, then repopulate the table with the data, then send it to printer.
Is there a better way to do it?
As I've answered here, I solved it by hiding columns before printing and restoring columns after printing:
// get column num from settings
int num = gridSettings.getColumnsOnPage();// first <num> columns of the table will be printed
final TableColumnModel model = table.getColumnModel();
// list of removed columns. After printing we add them back
final List<TableColumn> removed = new ArrayList<TableColumn>();
int columnCount = model.getColumnCount();
// hiding columns which are not used for printing
for(int i = num; i < columnCount; ++i){
TableColumn col = model.getColumn(num);
removed.add(col);
model.removeColumn(col);
}
// printing after GUI will be updated
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// table printing
try {
table.print(PrintMode.FIT_WIDTH, null, null, true, hpset, true); // here can be your printing
} catch (PrinterException e) {
e.printStackTrace();
}
// columns restoring
for(TableColumn col : removed){
model.addColumn(col);
}
}
});
For printing specific part of a JTable, just change a little bit this code.
The best way: just set column width to zero then it will be hidden:)
TableColumn column = table.getColumnModel().getColumn(i);
//backup first
int minWidth=column.getMinWidth();
int width=column.getPreferredWidth();
//to hide:
column.setMinWidth(0);
column.setPreferredWidth(0);
//to show it back:
column.setMinWidth(minWidth);
column.setPreferredWidth(width);

Categories

Resources