Component inside JList not painting; now resolved
I have set up a JList to work with its own ListModel and
ListCellRenderer. The symptom, my component does not
display any text. That is the list box is
completely blank. From the debugging, I saw it displayed the desired
text. And, we saw that the list box scrolled when there was more data
than can be displayed.
The problem turned out to be that I defined paint() rather than
paintComponent(). What was strange was that I was able to use other
classes extending Component that I wrote and return them
from the ListCellRenderer. These had the same mistake
of putting the display logic in paint() rather than paintComponent();
Yet those Components worked fine and this error in the class notes from
which
I taught our GUI course since 2001.
One of my students , Mr. Kevin Kraus,
elucidated the solution to this problem -- Thanks!
This was also discussed in this group in
relation to a post from John Creighton on September 2 2001.
Since, this is an easy error to make, it is worthwhile having the
reminder, here.
I did not see anything saying this in the FAQ but section 3.4
told our users not to use Component.getGraphics(). They were told
to override "paint()(AWT)" or "paintComponent()(Swing)"
I am sending a suggestion to Mr. Weidenfeller
of new wording to help people trouble shooting their
programs.
Here is my component definition:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class NumberComponent extends JComponent {
String FontName;
String ToDisplay;
int Size;
boolean Selected;
Font f;
void setSelected (boolean S){
Selected=S;
}
NumberComponent (String S) {
ToDisplay = S;
Size = 12;
FontName="Arial";
}
NumberComponent (String S, String F, int size) {
Size=size; FontName = F; ToDisplay = S;
}
public void paint (Graphics g) {
System.out.println ("font Name " + FontName + " Size " + Size);
if (!Selected) {
f = new Font (FontName,Font.PLAIN,Size);
}
else {
f = new Font (FontName,Font.BOLD,Size);
}
//g.setFont(f);
g.setColor(Color.black);
//g.fillRect(10,10,30,20);
g.drawString (ToDisplay,0,0);
System.out.println (" here " + ToDisplay + " hc " + hashCode());
}
public Dimension getMinimumSize() {
if (!Selected) {
f = new Font (FontName,Font.PLAIN,Size);
}
else {
f = new Font (FontName,Font.BOLD,Size);
}
int Width = getFontMetrics(f).stringWidth(ToDisplay);
int Height = getFontMetrics(f).getHeight();
System.out.println (" Width " + Width + "Height " + Height);
Dimension D = new Dimension (Width,Height);
return D;
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
public Dimension getMaximumSize() {
return getMinimumSize();
}
}
Here is the output from the list box that is using it to display:
@toolman#/home/leffstudent/412/final1 >java LMX Numbers.xml
Number Text 33333333Font is Size NC 7754385
Width 64Height 15
Number Text 433333334Font is Size NC 3541984
Width 72Height 15
Number Text 233333332Font is Size NC 4565111
Width 72Height 15
Number Text 33333333Font is Size NC 16164678
font Name Arial Size 12
here 33333333 hc 16164678
Number Text 433333334Font is Size NC 16795905
font Name Arial Size 12
here 433333334 hc 16795905
Number Text 233333332Font is Size NC 28904249
font Name Arial Size 12
here 233333332 hc 28904249
@toolman#/home/leffstudent/412/final1 >exit
exit
Here is the ListCellRenderer I defined:
import javax.swing.*;
import java.awt.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
class NR implements ListCellRenderer {
public Component getListCellRendererComponent (
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
Element N = (Element)value;
NodeList NL = N.getChildNodes();
Node TextNode = NL.item(0);
String NumberText = TextNode.getNodeValue();
String Font = N.getAttribute("Font");
String SizeText = N.getAttribute("Size");
System.out.print ("Number Text " + NumberText + "Font is " + Font + "
Size " + SizeText);
NumberComponent NC;
if (Font != null && Font.length() != 0 && SizeText!=null &&
SizeText.length()!= 0) {
int Size = Integer.parseInt(SizeText);
NC = new NumberComponent(NumberText,Font,Size);
}
else {
NC = new NumberComponent(NumberText);
}
NC.setSelected(isSelected);
System.out.println ("NC " + NC.hashCode());
return NC;
}
}