Reputation: 169
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.
Upvotes: 3
Views: 12952
Reputation: 168835
An alternative is to render the table as HTML in a JLabel
.
import java.awt.*;
import javax.swing.*;
public class HTMLTableDemo {
HTMLTableDemo() {
StringBuilder sb = new StringBuilder();
sb.append("<html><body><table border=1>");
sb.append("<tr>");
for ( String columnName : columnNames ) {
sb.append("<th>");
sb.append(columnName);
sb.append("</th>");
}
sb.append("</tr>");
for (Object[] row : data) {
sb.append("<tr>");
for (Object value : row) {
sb.append("<td>");
sb.append(value);
sb.append("</td>");
}
sb.append("</tr>");
}
sb.append("</table>");
JLabel html = new JLabel(sb.toString());
JOptionPane.showMessageDialog(null, html);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
new HTMLTableDemo();
}
};
SwingUtilities.invokeLater(r);
}
String[] columnNames = {
"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"
};
Object[][] data = {
{"Kathy", "Smith", "Snowboarding", 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)}
};
}
For rendering it to a Graphics
instance, see the LabelRenderTest.java
source on this answer.
Upvotes: 2
Reputation: 241
I got success in mapping one to one drawing using the below code:-
Panel1.java
package com.swing.data;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
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() >>>>>>>>>>>>>>>>>>>>>");
FontMetrics fm = g.getFontMetrics(font);
JTable table = getModel();
int columnCount = table.getModel().getColumnCount();
int rowCount = table.getModel().getRowCount();
int yLoc =10;
int rowHeight = 0 ;
int columnWidth = 0 ;
double w = 0;
double h = 0;
FontRenderContext frc = fm.getFontRenderContext();
g.setFont(font);
for(int r = 0 ; r < rowCount; r++)
{
int xLoc = 0 ;
int yPad = 0;
for(int c= 0 ; c< columnCount; c++)
{
Rectangle rect = table.getCellRect(r, c, true);
String displayString = table.getValueAt(r, c).toString();
columnWidth = rect.width;
rowHeight = rect.height;
w = (double)font.getStringBounds(displayString, frc).getWidth();
h = (double)font.getStringBounds(displayString, frc).getHeight();
//yPad = (int) Math.ceil((rowHeight - h)/2);
yPad = Math.abs((int)(rowHeight - h)/2);
System.out.println("displayString ::"+displayString + "rowHeight:" + rowHeight +"String height:" + h+"yPad:"+yPad +"xLoc:"+xLoc+"yLoc:"+yLoc);
g.drawString(displayString, xLoc , yLoc + rowHeight - yPad);
g.drawRect(xLoc, yLoc, columnWidth, rowHeight);
xLoc+= columnWidth + table.getIntercellSpacing().width;
}
yLoc+= rowHeight + table.getIntercellSpacing().height;
}
}
}
Thanks
Upvotes: 0
Reputation: 205835
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 after pack()
.
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.
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 call repaint
explicitly, listen to the TableModel
, or use JTable
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 use GridLayout(0, 1)
.
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.
Upvotes: 4