在面板上绘制JTable行和列 [英] Drawing JTable rows and columns on a Panel

查看:91
本文介绍了在面板上绘制JTable行和列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,我必须在画布上绘制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字体和边框。

解决方案

有几个问题是显而易见的:


  1. 您出现要使用退出的 JTable 的几何创建您自己的表格视图;这些大小在 pack()之后可能无效。

  2. 您循环遍历 adjustColumns ,但只有最后一列的宽度设置在 panel 中,然后它变成表格中显示的常量宽度。 / b>
  3. JTable 本身相比,您的实现将缩小比例,它使用 flyweight rendering ,图解这里 在调整框架大小时,您的面板消失;你应该明确地调用 repaint ,监听 TableModel ,或者使用 JTable 本身。


  4. 自Java 5以来, autoboxing 允许以下内容;比较:

      {John,Doe,Rowing,new Integer(3),new Boolean(true) } 
    {John,Doe,Rowing,3,true}


  5. 不要替换内容窗格; 添加()您的面板;比较:

      frame.setContentPane(newContentPane); 
    frame.add(newContentPane);


  6. 使用 GridLayout(3,0)表示误解;在一列中获得任意数量的行使用 GridLayout(0,1)


  7. 你扩展 JPanel ,注意Swing程序应该重载 paintComponent(),而不是覆盖 paint ();另请参阅 AWT和Swing中的绘画:绘画方法 em>



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:

  1. You appear to be creating your own table view using the geometry of an exiting JTable; those sizes may not be valid until after pack().

  2. You loop through the columns in adjustColumns, but only the last column width is set in panel, which then becomes the constant width seen in your table.

  3. Your implementation will scale poorly compared JTable itself, which uses flyweight rendering, illustrated here.

  4. Your panel disappears when the frame is resized; you should either call repaint explicitly, listen to the TableModel, or use JTable itself.

  5. Since Java 5, autoboxing allows the following; compare:

    {"John", "Doe", "Rowing", new Integer(3), new Boolean(true)}
    {"John", "Doe", "Rowing", 3, true}
    

  6. Don't replace the content pane; add() your panel to it; compare:

    frame.setContentPane(newContentPane);
    frame.add(newContentPane);
    

  7. Your use of GridLayout(3,0) suggests a misunderstanding; to get an arbitrary number of rows in one column use GridLayout(0, 1).

  8. As you extend JPanel, note that "Swing programs should override paintComponent() instead of overriding paint();" see also Painting in AWT and Swing: The Paint Methods.

这篇关于在面板上绘制JTable行和列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆