Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mapping of JTable rows and columns onto frame object

32 views
Skip to first unread message

keto

unread,
Sep 29, 2012, 11:50:01 PM9/29/12
to
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

Roedy Green

unread,
Sep 30, 2012, 2:44:07 PM9/30/12
to
On Sat, 29 Sep 2012 20:50:01 -0700 (PDT), keto
<ajay.p...@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>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.
--
Roedy Green Canadian Mind Products http://mindprod.com
The iPhone 5 is a low end Rolex.


John B. Matthews

unread,
Sep 30, 2012, 2:54:56 PM9/30/12
to
In article <8c11ba4d-3924-443e...@googlegroups.com>,
keto <ajay.p...@gmail.com> wrote:

> 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>

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>
0 new messages