Artikel ist eine einfache Modellklasse.Swing: Warum wird meine benutzerdefinierte Komponente nicht neu streichen?
ItemComponent ist eine Ansicht für ein Objekt, das nur einfache Rechtecke an einer bestimmten Stelle zeichnet. Eine Reihe von ItemComponent-Instanzen wird in eine übergeordnete Komponente eingefügt, die dem JFrame der Anwendung hinzugefügt wird (momentan nur eine einfache Shell).
Die Ansicht hat zwei verschiedene Anzeigestile. Ich möchte einige Eigenschaften des Modells anpassen und möglicherweise den Status ändern (der den Stil steuert) und dann update() aufrufen, um neu zu zeichnen.
Das Problem ist, soweit ich das beurteilen kann ... paint() wird nur einmal aufgerufen. repaint() scheint keine Wirkung zu haben.
Was ist los?
Ich bin kein Swing-Programmierer und habe das aus Beispielen zusammengestöpselt, also erwarte ich, dass es hier etwas Triviales sein kann, das ich nicht verstehe.
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);
}
}
}
Hinweis: ich in repaint verfolgt() und einen Punkt gefunden, wo isDisplayable() überprüft wurde, und es ist falsch zurück. Es stellt sicher, dass getPeer()! = Null ist.
Also hat meine Komponente keinen Partner? Was ist damit? Es wurde einem Container hinzugefügt, der selbst zum Rest der App hinzugefügt wird. Und es wird einmal gemalt, also weiß ich, dass es sichtbar ist.
Ein Peer ist nur für AWT-Komponenten verfügbar (der Peer ist die reale Komponente des nativen Fenstersystems, die zur Komponente gehört), die meisten Swing-Komponenten haben keinen Peer. Warum arbeitest du sowieso an addNotify? –