在面板上绘制JTable行和列 [英] Drawing JTable rows and columns on a Panel
问题描述
我正在编写一个应用程序,我必须在画布上绘制JTable组件。但是,我的几次尝试仍然无法绘制JTable的完美图片。我试图使用getCellRect api绘制使用JTable的特定单元格的大小,但是当数据很大时,无法在画布上绘制特定的单元格。以下是示例代码: - $ / $>
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;
私有地图columnSizes = new HashMap();
String [] columnNames = {名字,
姓氏,
运动,
年数,
素食主义者} ;
对象[] [] data = {
{Kathy,Smith,
SnowboardingXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,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,
速读,新Integer(20),new Boolean(true )},
{Joe,Brown,
Pool,new Integer(10),new Boolean(false)}
};
final JTable table = new JTable(data,columnNames);
Panel1面板;
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);
}
});
}
//创建滚动窗格并添加表格。
JScrollPane scrollPane = new JScrollPane(table);
//将滚动窗格添加到此面板。
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(面板);
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();
$ b 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(数据值:);
for(int i = 0; i< numRows; i ++){
System.out.print(row+ i +:); (int j = 0; j System.out.print(+ model.getValueAt(i,j));
}
System.out.println();
}
System.out.println(--------------------------);
$ b $ * b $ b *调整表格中所有列的宽度
* /
public void adjustColumns()
{
TableColumnModel tcm = table.getColumnModel();
for(int i = 0; i< tcm.getColumnCount(); i ++)
{
adjustColumn(i);
$ b $ * b $ b *调整表格中指定列的宽度
* /
public void adjustColumn(final int列)
{
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);
$ b $ * b $ b *根据列名计算宽度
* /
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);
返回c.getPreferredSize()。width;
}
/ *
*根据
*给定列中最宽的单元格渲染器计算宽度。
* /
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)) ;
//我们已经超过了最大宽度,不需要检查其他行
if(preferredWidth> = maxWidth)
break;
}
return preferredWidth;
$ b $ * b $ b *获取指定单元格的首选宽度
* /
private int getCellDataWidth(int row,int column)
{
//为单元格渲染渲染器以计算首选宽度
TableCellRenderer cellRenderer = table.getCellRenderer(row,column);
组件c = table.prepareRenderer(cellRenderer,row,column);
int width = c.getPreferredSize()。width + table.getIntercellSpacing()。width;
返回宽度;
$ b $ * b $ b *用新计算的宽度更新TableColumn
* /
private void updateTableColumn(int column,int width)
{
final TableColumn tableColumn = table.getColumnModel()。getColumn(column);
if(!tableColumn.getResizable())return;
width + = spacing;
//不缩小列宽
width = Math.max(width,tableColumn.getPreferredWidth());
columnSizes.put(tableColumn,new Integer(tableColumn.getWidth()));
table.getTableHeader()。setResizingColumn(tableColumn);
tableColumn.setWidth(width);
}
/ **
*创建GUI并显示它。为了线程安全,应该从
* event-dispatch线程调用
*这个方法。
* /
private static void createAndShowGUI(){
//创建并设置窗口。
JFrame frame = new JFrame(SimpleTableDemo);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建并设置内容窗格。
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); //内容窗格必须是不透明的
frame.setContentPane(newContentPane);
//显示窗口。
frame.pack();
frame.setVisible(true);
}
public static void main(String [] args){
//安排事件派发线程的作业:
//创建并显示应用程序的GUI。
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndShowGUI();
}
});
}
}
class Panel1扩展JPanel
{
int x;
int y;
int width;
int height;
String str;
JTable模型;
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;
}
}
};
我修改了这段代码,大小和边界。我想绘制所有这些表定制,请看看并建议一些东西。
谢谢
SimpleTableDemo.java
package com.swing.data;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class SimpleTableDemo extends JPanel
{
private boolean DEBUG = false;
private int spacing = 6;
私有地图columnSizes = new HashMap();
String [] columnNames = {名字,姓氏,运动,年数,素食};
Object [] [] data =
{
{Kathy,Smith,SnowboardingXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,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)}
};
JTable table = new JTable(data,columnNames);
Panel1面板;
public SimpleTableDemo()
{
super(new GridLayout(3,0));
table.setPreferredScrollableViewportSize(new Dimension(500,70));
if(DEBUG)
{
table.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
printDebugData(table);
}
});
}
//创建滚动窗格并将表添加到它。
JScrollPane scrollPane = new JScrollPane(table);
//将滚动窗格添加到此面板。
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(面板);
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();
$ b $ private void jNumberComboBoxSizeActionPerformed(JComboBox jNumberComboBoxSize)
{
int fontSize = Integer.parseInt(jNumberComboBoxSize.getSelectedItem()。toString());
table.setRowHeight(fontSize);
setBorder(new Font(Serif,Font.BOLD,fontSize));
table.setFont(new Font(Serif,Font.BOLD,fontSize));
panel.setFont(new Font(Serif,Font.BOLD,fontSize));
Rectangle rect = table.getCellRect(0,0,true);
panel.setX(0);
panel.setY(0);
panel.setHeight(rect.height);
panel.setStr(table.getModel()。getValueAt(0,0).toString());
panel.setModel(table);
panel.repaint();
table.revalidate();
}
public void setBorder(Font f)
{
BorderCellRenderer cellRenderer = new BorderCellRenderer();
cellRenderer.setColumnBorder(BorderFactory.createLineBorder(Color.BLACK,2));
cellRenderer.setFont(f);
table.getColumnModel()。getColumn(0).setCellRenderer(cellRenderer);
table.getColumnModel()。getColumn(1).setCellRenderer(cellRenderer);
$ b private void printDebugData(JTable table)
{
int numRows = table.getRowCount();
int numCols = table.getColumnCount();
javax.swing.table.TableModel model = table.getModel();
System.out.println(数据值:);
for(int i = 0; i< numRows; i ++)
{
System.out.print(row+ i +:); (int j = 0; j {
System.out.print(+ model.getValueAt(i,j));
}
System.out.println();
}
System.out.println(--------------------------);
$ b $ * b $ b *调整表格中所有列的宽度
* /
public void adjustColumns()
{
TableColumnModel tcm = table.getColumnModel();
for(int i = 0; i< tcm.getColumnCount(); i ++)
{
adjustColumn(i);
$ b $ * b $ b *调整表格中指定列的宽度
* /
public void adjustColumn(int列)
{
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);
$ b $ * b $ b *根据列名计算宽度
* /
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);
返回c.getPreferredSize()。width;
}
/ *
*根据
*给定列中最宽的单元格渲染器计算宽度。
* /
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)) ;
if(preferredWidth> = maxWidth)
break;
}
return preferredWidth;
$ b $ * b $ b *获取指定单元格的首选宽度
* /
private int getCellDataWidth(int row,int column)
{
//为单元格渲染渲染器以计算首选宽度
TableCellRenderer cellRenderer = table.getCellRenderer(row,column);
组件c = table.prepareRenderer(cellRenderer,row,column);
int width = c.getPreferredSize()。width + table.getIntercellSpacing()。width;
返回宽度;
$ b $ * b $ b *用新计算的宽度更新TableColumn
* /
private void updateTableColumn(int column,int width)
{
final TableColumn tableColumn = table.getColumnModel()。getColumn(column);
if(!tableColumn.getResizable())return;
width + = spacing;
//不缩小列宽
width = Math.max(width,tableColumn.getPreferredWidth());
columnSizes.put(tableColumn,new Integer(tableColumn.getWidth()));
table.getTableHeader()。setResizingColumn(tableColumn);
tableColumn.setWidth(width);
}
/ **
*创建GUI并显示它。为了线程安全,应该从
* event-dispatch线程调用
*这个方法。
* /
private static void createAndShowGUI()
{
//创建并设置窗口。
JFrame frame = new JFrame(SimpleTableDemo);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建并设置内容窗格。
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); //内容窗格必须是不透明的
frame.setContentPane(newContentPane);
//显示窗口。
frame.pack();
frame.setVisible(true);
}
public static void main(String [] args)
{
//为事件派发线程安排作业:
//创建并显示此应用程序的GUI。
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndShowGUI();
}
});
}
}
** Panel1.java **
package com.swing.data;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JPanel;
import javax.swing.JTable;
class Panel1扩展JPanel
{
int x;
int y;
int width;
int height;
String str;
JTable模型;
字体字体;
public Font getFont(){
return font;
}
public void setFont(Font font){
this.font = font;
}
public void setModel(JTable model)
{
this.model = model;
}
public JTable getModel()
{
return 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);
// String str = model.getModel()。getValueAt(row,col).toString();
// int xloc =(x + 10);
// int yloc = y +10;
//// System.out.println(xloc:+ xloc);
//// System.out.println(yloc:+ yloc);
//// System.out.println(width:+ width);
//// System.out.println(height:+ height);
//// System.out.println(str:+ str);
//
// g.drawString(model.getModel()。getValueAt(row,col).toString(),x + 10,y + 10);
// x = x + width;
//}
// x = initX;
// y = y + height;
//
//}
System.out.println(Inside paint()>>>>>>>>> >>>>>>>>>>>>中);
JTable table = getModel();
int columnCount = table.getModel()。getColumnCount();
int rowCount = table.getModel()。getRowCount();
int yLoc = 10;
int rowHeight = 0;
int columnWidth = 0;
g.setFont(font);
for(int r = 0; r {
int xLoc = 0;
for(int c = 0; c< columnCount; c ++)
{
Rectangle rect = table.getCellRect(r,c,true);
columnWidth = rect.width;
rowHeight = rect.height;
g.drawRect(xLoc,yLoc,columnWidth,rowHeight);
String displayString = table.getValueAt(r,c).toString();
System.out.println(displayString ::+ displayString);
g.drawString(displayString,xLoc + 5,yLoc + 15);
xLoc + = columnWidth;
}
yLoc + = rowHeight;
}
}
}
** BorderCellRenderer.java **
package com.swing.data;
import java.awt。*;
import javax.swing。*;
import javax.swing.table。*;
import javax.swing.border。*;
$ b / **
* @version 1.0 03/06/99
* /
公共类BorderCellRenderer扩展JLabel
实现TableCellRenderer {
受保护的边框noFocusBorder;
受保护的边界columnBorder;
保护字体字体;
public Font getFont(){
return font;
}
public void setFont(Font font){
this.font = font;
BorderCellRenderer(){
noFocusBorder = new EmptyBorder(1,2,1,2);
setOpaque(true);
$ b $公共组件getTableCellRendererComponent(JTable表,Object值,
布尔isSelected,布尔hasFocus,int行,int列){$ b $ setText((value == null)?:value.toString());
setBorder(columnBorder);
setFont(font);
返回此;
}
public void setColumnBorder(Border border){
columnBorder = border;
}
public Border getColumnBorder(){
return columnBorder;
$ / code>
请建议重新绘制相应的JTable字体和边框。
有几个问题是显而易见的:
-
您出现要使用退出的
JTable
的几何创建您自己的表格视图;这些大小在pack()
之后可能无效。 您循环遍历 -
与
JTable 本身相比,您的实现将缩小比例,它使用 flyweight rendering ,图解这里。 在调整框架大小时,您的 面板
消失;你应该明确地调用repaint
,监听TableModel
,或者使用JTable
本身。 -
自Java 5以来, autoboxing 允许以下内容;比较:
{John,Doe,Rowing,new Integer(3),new Boolean(true) }
{John,Doe,Rowing,3,true}
-
不要替换内容窗格;
添加()
您的面板;比较:frame.setContentPane(newContentPane);
frame.add(newContentPane);
-
使用
GridLayout(3,0)
表示误解;在一列中获得任意数量的行使用GridLayout(0,1)
。 -
你扩展
JPanel
,注意Swing程序应该重载paintComponent()
,而不是覆盖paint ()
;另请参阅 AWT和Swing中的绘画:绘画方法 em> 。
adjustColumns
,但只有最后一列的宽度设置在 panel
中,然后它变成表格中显示的常量宽度。 / b>
I am writing one application in which I have to draw JTable component on a canvas. But after my several attempts still unable to draw a completely perfect picture of a JTable. I tried to draw using sizes of specific cells of a JTable using getCellRect api, but when data is big not able to draw specific cells on the canvas. Here 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;
}
}
};
I modified this code to redraw column cells with Font sizes and borders. I want to draw all these table customizations, Please take a look and suggest something.
Thanks
SimpleTableDemo.java
package com.swing.data;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
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)}
};
JTable table = new JTable(data, columnNames);
Panel1 panel;
public SimpleTableDemo()
{
super(new GridLayout(3,0));
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
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);
setBorder(new Font("Serif", Font.BOLD, fontSize));
table.setFont(new Font("Serif", Font.BOLD, fontSize));
panel.setFont(new Font("Serif", Font.BOLD, fontSize));
Rectangle rect = table.getCellRect(0,0,true);
panel.setX(0);
panel.setY(0);
panel.setHeight(rect.height);
panel.setStr(table.getModel().getValueAt(0,0).toString());
panel.setModel(table);
panel.repaint();
table.revalidate();
}
public void setBorder(Font f)
{
BorderCellRenderer cellRenderer = new BorderCellRenderer();
cellRenderer.setColumnBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
cellRenderer.setFont(f);
table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
table.getColumnModel().getColumn(1).setCellRenderer(cellRenderer);
}
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(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));
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();
}
});
}
}
**Panel1.java**
package com.swing.data;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JPanel;
import javax.swing.JTable;
class Panel1 extends JPanel
{
int x;
int y;
int width;
int height;
String str;
JTable model;
Font font;
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
public void setModel(JTable model)
{
this.model = model;
}
public JTable getModel()
{
return 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);
// String str = model.getModel().getValueAt(row, col).toString();
// int xloc = (x+10);
// int yloc = y +10;
//// System.out.println("xloc : "+xloc);
//// System.out.println("yloc : "+yloc);
//// System.out.println("width : "+width);
//// System.out.println("height : "+height);
//// System.out.println("str : "+str);
//
// g.drawString(model.getModel().getValueAt(row,col).toString(),x + 10,y + 10);
// x = x + width;
// }
// x = initX;
// y = y + height;
//
// }
System.out.println("Inside paint() >>>>>>>>>>>>>>>>>>>>>");
JTable table = getModel();
int columnCount = table.getModel().getColumnCount();
int rowCount = table.getModel().getRowCount();
int yLoc = 10;
int rowHeight = 0 ;
int columnWidth = 0 ;
g.setFont(font);
for(int r = 0 ; r < rowCount; r++)
{
int xLoc = 0 ;
for(int c= 0 ; c< columnCount; c++)
{
Rectangle rect = table.getCellRect(r, c, true);
columnWidth = rect.width;
rowHeight = rect.height;
g.drawRect(xLoc, yLoc, columnWidth, rowHeight);
String displayString = table.getValueAt(r, c).toString();
System.out.println("displayString ::"+displayString);
g.drawString(displayString, xLoc+5, yLoc+15);
xLoc+= columnWidth;
}
yLoc+= rowHeight;
}
}
}
**BorderCellRenderer.java**
package com.swing.data;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
/**
* @version 1.0 03/06/99
*/
public class BorderCellRenderer extends JLabel
implements TableCellRenderer {
protected Border noFocusBorder;
protected Border columnBorder;
protected Font font;
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
public BorderCellRenderer() {
noFocusBorder = new EmptyBorder(1, 2, 1, 2);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setText((value == null) ? "" : value.toString());
setBorder(columnBorder);
setFont(font);
return this;
}
public void setColumnBorder(Border border) {
columnBorder = border;
}
public Border getColumnBorder() {
return columnBorder;
}
}
Please suggest something to redraw the appropriate JTable font and borders.
Several problems are apparent:
You appear to be creating your own table view using the geometry of an exiting
JTable
; those sizes may not be valid until afterpack()
.You loop through the columns in
adjustColumns
, but only the last column width is set inpanel
, which then becomes the constant width seen in your table.Your implementation will scale poorly compared
JTable
itself, which uses flyweight rendering, illustrated here.Your
panel
disappears when the frame is resized; you should either callrepaint
explicitly, listen to theTableModel
, or useJTable
itself.Since Java 5, autoboxing allows the following; compare:
{"John", "Doe", "Rowing", new Integer(3), new Boolean(true)} {"John", "Doe", "Rowing", 3, true}
Don't replace the content pane;
add()
your panel to it; compare:frame.setContentPane(newContentPane); frame.add(newContentPane);
Your use of
GridLayout(3,0)
suggests a misunderstanding; to get an arbitrary number of rows in one column useGridLayout(0, 1)
.As you extend
JPanel
, note that "Swing programs should overridepaintComponent()
instead of overridingpaint()
;" see also Painting in AWT and Swing: The Paint Methods.
这篇关于在面板上绘制JTable行和列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!