Item is a simple model class.
ItemComponent is a view for an Item which just draws simple rectangles in a given spot. A bunch of ItemComponent instances are put into a parent component that is added to the JFrame of the application (just a simple shell right now).
The view has two different display styles. I want to adjust some properties of the model, and possibly change the state (which controls the style), and then call update() to repaint.
The problem is, as far as I can tell... paint() is only EVER called once. repaint() seems to have no effect.
What's wrong?
I'm not a Swing programmer and cobbled this together from examples, so I expect it may be something trivial here I don't understand.
public class ItemComponent extends JComponent implements ItemView {
private static final Color COLOR_FILL_NORMAL = new Color(0x008080ff);
private static final Color COLOR_FILL_TARGET = Color.LIGHT_GRAY;
private static final Color COLOR_OUTLINE = new Color(0x00333333);
Item item;
RoundRectangle2D rect;
State state = State.NORMAL;
float alpha = 1.0f;
public ItemComponent(Item item) {
this.item = item;
this.rect = new RoundRectangle2D.Double(0, 0, 0, 0, 5, 5);
item.setView(this);
}
public void setState(State state) {
this.state = state;
}
public void update() {
System.out.println("ItemComponent.update");
setLocation(item.getLeft(), 1);
setSize(item.getWidth(), getParent().getHeight()-1);
rect.setRoundRect(0, 0, getWidth()-1, getHeight()-1, 5, 5);
repaint();
//paintImmediately(getBounds());
}
@Override
public void addNotify() {
update();
}
@Override
public void paint(Graphics g) {
System.out.println("paint");
Graphics2D g2 = (Graphics2D)g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (state == State.NORMAL) {
System.out.println("draw normal");
g2.setPaint(COLOR_FILL_NORMAL); // light blue
g2.fill(rect);
g2.setPaint(COLOR_OUTLINE);
g2.draw(rect);
}
else if (state == State.TARGET) {
System.out.println("draw target");
g2.setPaint(COLOR_FILL_TARGET);
g2.fill(rect);
float[] dashPattern = { 8, 5 };
g2.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10, dashPattern, 0));
g.setColor(COLOR_OUTLINE);
g2.draw(rect);
}
}
}
Hint: I traced into repaint() and found a point where isDisplayable() was being checked, and it's returning false. It makes sure that getPeer() != null.
So my component has no peer? What's up with that? It's been added to a container which itself is added to the rest of the app. And it gets painted once, so I know it's visible.