Kathi Kathi - 19 days ago 6
Java Question

Change JTable non Content background color

I am writing a custom theme which is an extension of

NimbusLookAndFeel
.
I want to redesign the table theme like

enter image description here

My Table theme code

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;

import javax.swing.Painter;

import infotrax.nimbus.NimbusBaseUI;

public class TableTheme {

protected int strokeSize = 2; // changed to 2 from 1 to fill the gap in corners
protected Color shadowColor = new Color(128, 128, 128, 140);
protected boolean shady = true;
protected boolean highQuality = false;
/** Double values for Horizontal and Vertical radius of corner arcs */
protected Dimension arcs = new Dimension(10, 10);
/** Distance between shadow border and opaque panel border */
protected int shadowGap = 1;
/** The offset of shadow. */
protected int shadowOffset = 1; // width of the shadow
/** The transparency value of shadow. ( 0 - 255) */
protected int shadowAlpha = 130;

public TableTheme(NimbusBaseUI nimbusUI) {

Insets ins = new Insets(2,2,2,2);
nimbusUI.getDefaults().put("Table.contentMargins",ins
);


nimbusUI.getDefaults().put("Table.background",
new Color(255, 255, 255)); // Modified to set background color of table to be white 01/08/2016




nimbusUI.getDefaults().put(
"Table.borderPainter",
new TableBorderPaintGradient(new Color(255, 255, 255), new Color(255,
255, 255)));

nimbusUI.getDefaults().put(
"Table[Enabled].borderPainter",
new TableBorderPaintGradient(new Color(255, 255, 255), new Color(255,
255, 255)));

nimbusUI.getDefaults().put(
"Table[Enabled+Selected].borderPainter",
new TableBorderPaintGradient(new Color(255, 255, 255), new Color(255,
255, 255)));

nimbusUI.getDefaults().put(
"Table[Selected].borderPainter",
new TableBorderPaintGradient(new Color(255, 255, 255), new Color(255,
255, 255)));

nimbusUI.getDefaults().put(
"Table[Focused].borderPainter",
new TableBorderPaintGradient(new Color(255, 255, 255), new Color(255,
255, 255)));

nimbusUI.getDefaults().put(
"Table[Disabled].borderPainter",
new TableBorderPaintGradient(new Color(255, 255, 255), new Color(255,
255, 255)));

nimbusUI.getDefaults().put("TableHeader.font",
new Font("Myriad Pro Light", Font.BOLD, 13));
// Table Header color
nimbusUI.getDefaults()
.put("TableHeader:\"TableHeader.renderer\"[MouseOver].backgroundPainter",
new TableheaderPainter(new Color(188,188,188),
new Color(188,188,188)));
nimbusUI.getDefaults()
.put("TableHeader:\"TableHeader.renderer\"[Enabled].backgroundPainter",
new TableheaderPainter(new Color(188,188,188),
new Color(188,188,188)));

}

public class TableheaderPainter implements Painter {

private static final long serialVersionUID = 1L;
private Color light, dark;
private GradientPaint gradPaint;

public TableheaderPainter(Color light, Color dark) {
this.light = light;
this.dark = dark;
}

@Override
public void paint(Graphics2D paramGraphics2D, Object paramT,
int paramInt1, int paramInt2) {
paramGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gradPaint = new GradientPaint((paramInt1 / 2.0f), 0, light,
(paramInt1 / 2.0f), (paramInt2 / 2.0f), dark, true);
paramGraphics2D.setPaint(gradPaint);
paramGraphics2D.fillRoundRect(0, 0, (paramInt1 - 0),
(paramInt2 - 0), 0, 0);

}
}



public class Tablebackground_Painter implements Painter {

private Color light, dark;
private GradientPaint gradPaint;
int shadowGap = 2;

public Tablebackground_Painter(Color light, Color dark) {
this.light = light;
this.dark = dark;
}

@Override
public void paint(Graphics2D g, Object c, int w, int h) {

Color shadowColorA = new Color(shadowColor.getRed(),
shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
if (highQuality) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
if (shady) {
g.setColor(shadowColorA);
g.fillRoundRect(shadowOffset,// X position
shadowOffset,// Y position
w - strokeSize - shadowOffset, // width
h - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
} else {
shadowGap = 1;
}
gradPaint = new GradientPaint((w / 2.0f), 0, new Color(255, 255,
255), (w / 2.0f), (h / 2.0f), new Color(255, 255, 255),
false);
g.setPaint(gradPaint);

g.fillRoundRect(0, 0, w - shadowGap, h - shadowGap, arcs.width,
arcs.height);
g.setColor(Color.GREEN);
g.setStroke(new BasicStroke(strokeSize));
g.drawRoundRect(0, 0, w - shadowGap, h - shadowGap, arcs.width,
arcs.height);
g.setStroke(new BasicStroke());

}
}

public class TableBorderPainter implements Painter {
private Color light, dark;
private GradientPaint gradPaint;

public TableBorderPainter(Color light, Color dark) {
this.light = light;
this.dark = dark;
}

@Override
public void paint(Graphics2D g, Object c, int w, int h) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gradPaint = new GradientPaint((w / 2.0f), 0, new Color(255, 255,
255), (w / 2.0f), (h / 2.0f), new Color(255, 255, 255), true); // making background of border paint to white to match the list background
g.setPaint(gradPaint);
g.fillRoundRect(0, 0, (w - 0), (h - 0), 10, 10);
RoundRectangle2D roundedRectangle = new RoundRectangle2D.Float(0,
0, w - 1, h - 1, 10, 10);
g.setColor(Color.RED); // here we are making red border color for list
g.draw(roundedRectangle);
}

}


public class TableBorderPaintGradient implements Painter {

private Color light, dark;
private GradientPaint gradPaint;
protected int strokeSize = 1;
protected Color shadowColor = new Color(128, 128, 128, 140);
/** Sets if it drops shadow */
protected boolean shady = true;
/** Sets if it has an High Quality view */
protected boolean highQuality = false;
/** Double values for Horizontal and Vertical radius of corner arcs */
protected Dimension arcs = new Dimension(10, 10);
/** Distance between shadow border and opaque panel border */
protected int shadowGap = 1;
/** The offset of shadow. */
protected int shadowOffset = 1; // width of the shadow
/** The transparency value of shadow. ( 0 - 255) */
protected int shadowAlpha = 130;

public TableBorderPaintGradient(Color light, Color dark) {
this.light = light;
this.dark = dark;
}

@Override
public void paint(Graphics2D g, Object object, int w, int h) {

Color shadowColorA = new Color(shadowColor.getRed(),
shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
if (highQuality) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
if (shady) {
g.setColor(shadowColorA);
g.drawRoundRect(0, 0, w - shadowGap, h - shadowGap, arcs.width,
arcs.height);
} else {
shadowGap = 1;
}
gradPaint = new GradientPaint(0, 0, light, 0, h * .5f, dark, false);
g.setPaint(gradPaint);
g.drawRoundRect(shadowOffset,// X position
shadowOffset,// Y position
w - strokeSize - shadowOffset, // width
h - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
g.setColor(new Color(166,166,166));
g.setStroke(new BasicStroke(strokeSize));
g.drawRoundRect(shadowOffset,// X position
shadowOffset,// Y position
w - strokeSize - shadowOffset, // width
h - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
/* Changed to fillRoundedRect to drawRoundRect as per veryant suggestion */
g.setStroke(new BasicStroke());

}

}


}


And extend the
NimbusLookAndFeel
and set as default to apply all my components in Java NimbusBaseUI

import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
public class NimbusBaseUI extends NimbusLookAndFeel {
public NimbusBaseUI() {
super(); // Initialisation and installating
try {
new TableTheme(this);
UIManager.setLookAndFeel(this);
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public void initialize() {
// TODO Auto-generated method stub
super.initialize();
}

}


My Mainclass looks like this

import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;

class NimbusBaseDemo extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JTextField jtxt, txtDisEnabled;
int i;

private UIManager.LookAndFeelInfo[] lafs;

public NimbusBaseDemo() {
try {

// Set nimbus look and feel. nimbusBase works only for it.
new NimbusBaseUI();

} catch (Exception e) {
e.printStackTrace();
}

setTitle("Nimbus Base Demo");
setSize(400, 400);
setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
String columnNames[] = { "Column 1", "Column 2", "Column 3" ,"Column 4"};
String dataValues[][] = { { "12", "234", "67", " " },
{ "-123", "43", "853", "" }, { "93", "89.2", "109",""},
{ "279", "9033", "3092",""} };

JTable table1 = new JTable(dataValues, columnNames);
JScrollPane scrollPane = new JScrollPane(table1);
add(scrollPane);



}

public static void main(String args[]) {

new NimbusBaseDemo();
}
}


Finally I got result as

enter image description here

But I am not able to change the backgroud of JTable (Non content area) to white...

Please suggest.

Answer

To use the full space of the JTable component with rows, you need to set the setFillsViewportHeightparameter:

table.setFillsViewportHeight(true);

This will extend the white area to the bottom of the table.

Here is the doc saying:

Sets whether or not this table is always made large enough to fill the height of an enclosing viewport. If the preferred height of the table is smaller than the viewport, then the table will be stretched to fill the viewport. In other words, this ensures the table is never smaller than the viewport. The default for this property is false.

Without this, it is just the JScrollPane that is visible (or the component where the JTable is inserted in) so it is that background that needs to be updated.

PS: this is not really a theme problem here since this is the expected behavior of JTable to use only the needed space unless you tell it to use the full space.