Mapping of JTable rows and columns onto frame object

K

keto

Hi,

I am using Java Graphics api. Like to map my JTable rows and columns onto the canvas with exact dimensions. I tried using jTable.getCellRect() api to get the width, height of a cell and map it on the panel using graphics object. But it gives me the incorrect dimensions. Following is the sample code.

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.*;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.table.*;
import java.util.*;
import java.awt.*;

public class SimpleTableDemo extends JPanel {
private boolean DEBUG = false;
private int spacing = 6;
private Map columnSizes = new HashMap();
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};

Object[][] data = {
{"Kathy", "Smith",
"SnowboardingXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};

final JTable table = new JTable(data, columnNames);
Panel1 panel;

public SimpleTableDemo() {
super(new GridLayout(3,0));


table.setPreferredScrollableViewportSize(new Dimension(500, 70));
//table.setFillsViewportHeight(true);

if (DEBUG) {
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
printDebugData(table);
}
});
}

//Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);

//Add the scroll pane to this panel.
add(scrollPane);

panel = new Panel1();
Rectangle rect = table.getCellRect(0,0,true);

panel.setX(table.getWidth());
panel.setY(0);
panel.setWidth(rect.width);
panel.setHeight(rect.height);
panel.setStr(table.getModel().getValueAt(0,0).toString());
panel.setModel(table);

add(panel);

final JComboBox jNumberComboBoxSize = new JComboBox();
jNumberComboBoxSize.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "11", "12", "14", "16", "18", "20", "24", "30", "36", "48", "72" }));
jNumberComboBoxSize.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jNumberComboBoxSizeActionPerformed(jNumberComboBoxSize);
}
});

JPanel panel2 = new JPanel();
panel2.add(jNumberComboBoxSize);

add(panel2);
adjustColumns();

}

private void jNumberComboBoxSizeActionPerformed(JComboBox jNumberComboBoxSize)
{
int fontSize = Integer.parseInt(jNumberComboBoxSize.getSelectedItem().toString());
table.setRowHeight(fontSize);
table.setFont(new Font("Serif", Font.BOLD, fontSize));
Rectangle rect = table.getCellRect(0,0,true);
panel.setX(0);
panel.setY(0);
// panel.setWidth(rect.width);
panel.setHeight(rect.height);
panel.setStr(table.getModel().getValueAt(0,0).toString());
panel.setModel(table);
panel.repaint();
table.revalidate();
}

private void printDebugData(JTable table) {
int numRows = table.getRowCount();
int numCols = table.getColumnCount();
javax.swing.table.TableModel model = table.getModel();

System.out.println("Value of data: ");
for (int i=0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j=0; j < numCols; j++) {
System.out.print(" " + model.getValueAt(i, j));
}
System.out.println();
}
System.out.println("--------------------------");
}

/*
* Adjust the widths of all the columns in the table
*/
public void adjustColumns()
{
TableColumnModel tcm = table.getColumnModel();

for (int i = 0; i < tcm.getColumnCount(); i++)
{
adjustColumn(i);
}
}

/*
* Adjust the width of the specified column in the table
*/
public void adjustColumn(final int column)
{
TableColumn tableColumn = table.getColumnModel().getColumn(column);

if (! tableColumn.getResizable()) return;

int columnHeaderWidth = getColumnHeaderWidth( column );
int columnDataWidth = getColumnDataWidth( column );
int preferredWidth = Math.max(columnHeaderWidth, columnDataWidth);
panel.setWidth(preferredWidth);
updateTableColumn(column, preferredWidth);
}

/*
* Calculated the width based on the column name
*/
private int getColumnHeaderWidth(int column)
{
TableColumn tableColumn = table.getColumnModel().getColumn(column);
Object value = tableColumn.getHeaderValue();
TableCellRenderer renderer = tableColumn.getHeaderRenderer();

if (renderer == null)
{
renderer = table.getTableHeader().getDefaultRenderer();
}

Component c = renderer.getTableCellRendererComponent(table, value, false, false, -1, column);
return c.getPreferredSize().width;
}

/*
* Calculate the width based on the widest cell renderer for the
* given column.
*/
private int getColumnDataWidth(int column)
{
int preferredWidth = 0;
int maxWidth = table.getColumnModel().getColumn(column).getMaxWidth();

for (int row = 0; row < table.getRowCount(); row++)
{
preferredWidth = Math.max(preferredWidth, getCellDataWidth(row, column));

// We've exceeded the maximum width, no need to check other rows

if (preferredWidth >= maxWidth)
break;
}

return preferredWidth;
}

/*
* Get the preferred width for the specified cell
*/
private int getCellDataWidth(int row, int column)
{
// Inovke the renderer for the cell to calculate the preferred width

TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
Component c = table.prepareRenderer(cellRenderer, row, column);
int width = c.getPreferredSize().width + table.getIntercellSpacing().width;

return width;
}

/*
* Update the TableColumn with the newly calculated width
*/
private void updateTableColumn(int column, int width)
{
final TableColumn tableColumn = table.getColumnModel().getColumn(column);

if (! tableColumn.getResizable()) return;

width += spacing;

// Don't shrink the column width

width = Math.max(width, tableColumn.getPreferredWidth());


columnSizes.put(tableColumn, new Integer(tableColumn.getWidth()));
table.getTableHeader().setResizingColumn(tableColumn);
tableColumn.setWidth(width);
}

/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);

//Display the window.
frame.pack();
frame.setVisible(true);
}

public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

class Panel1 extends JPanel
{
int x;
int y;
int width;
int height;
String str;
JTable model;

public void setModel(JTable model)
{
this.model = model;
}

public void setX(int x)
{
this.x = x;
}

public void setY(int y)
{
this.y = y;
}

public void setWidth(int w)
{
this.width = w;
}

public void setHeight(int h)
{
this.height = h;
}

public void setStr(String s)
{
this.str = s;
}

public void paint(Graphics g)
{
super.paint(g);
int initX= 0;
for(int row=0;row < 5; ++row)
{
initX = x;
for (int col=0;col < 5;++col)
{
g.drawRect(x,y,width,height);
g.drawString(model.getModel().getValueAt(row,col).toString(),x + 10,y +10);
x = x + width;
}
x = initX;
y = y + height;

}

}
};
Please help to redraw a JTable cell row and height on JPanel.

Thanks,
Keto
 
R

Roedy Green

I am using Java Graphics api. Like to map my JTable rows and columns onto t=
he canvas with exact dimensions

This is not recommended. The problem is on different platforms the
fonts have different metrics. You have to dynamically adjust. That is
what layouts do.
 
J

John B. Matthews

keto said:
I am using Java Graphics api. Like to map my JTable rows and columns onto the
canvas with exact dimensions. I tried using jTable.getCellRect() api to get
the width, height of a cell and map it on the panel using graphics object.
But it gives me the incorrect dimensions. Following is the sample code.
[...]
Please help to redraw a JTable cell row and height on JPanel.

Cross-posted here: <http://stackoverflow.com/a/12663970/230513>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top