Reputation: 709
I have a strange problem that probably stems from lack of understanding of how Swing works. When, for the first time since program start, I attempt to render the panel inside a window frame anew as soon as I press one of the alphabetic keys, the character in question is painted very briefly on the panel, before the panel turns white again.
On subsequent key strokes the program then behaves as expected: the panel re-renders with the character associated with the pressed key.
Since the character IS painted on the first key stroke, the fact, that it disappears immediately afterwards must mean the panel is rendered AGAIN, thus overriding the previous contents.
Here's the code:
// Main.java
public class Main {
public static void main(String[] args) {
new GlyphFrame(new GlyphPanel());
}
}
// ---------------------------------------------------
// GlyphFrame.java
import javax.swing.JFrame;
public class GlyphFrame extends JFrame {
private static final long serialVersionUID = -7754180294993638709L;
private final int WIDTH = 500;
private final int LENGTH = 400;
public GlyphFrame(GlyphPanel panel){
this.add(panel);
this.setSize(WIDTH, LENGTH);
this.setVisible(true);
}
}
// ---------------------------------------------------
// GlyphPanel.java
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
public class GlyphPanel extends JPanel {
private static final long serialVersionUID = -6330730323655696958L;
public GlyphPanel(){
this.setBackground(Color.WHITE);
this.setFocusable(true);
this.requestFocusInWindow();
this.setFont(new Font("Dialog", Font.PLAIN, 12));
this.addKeyListener(new GlyphKeyListener(this));
}
private void paintPanel(Graphics g, char c){
super.paintComponent(g);
g.drawString("" + c, 10, 10);
g.setColor(this.getBackground());
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLACK);
g.drawString("" + c, 10, 10);
}
private class GlyphKeyListener implements KeyListener{
private GlyphPanel panel;
private int i = 0;
public GlyphKeyListener(GlyphPanel panel){
this.panel = panel;
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() >= KeyEvent.VK_A && e.getKeyCode() <= KeyEvent.VK_Z){
System.out.println("Call number " + (++i));
panel.paintPanel(panel.getGraphics(), e.getKeyChar());
}
}
@Override
public void keyReleased(KeyEvent e) {}
}
}
EDIT: Thanks for answering. Now I understand how painting is supposed to work in Swing.
If I need the panel to redraw itself I simply call repaint()
which makes the system call paintComponent(Graphics g)
. Thus, whatever I want to paint I put it in an overridden paintComponent()
method. paintComponent()
is never called directly. Only use repaint()
.
Upvotes: 2
Views: 385
Reputation: 10332
You shouldn't call paintPanel directly. swing manages painting itself. Instead of that you should do the following:
That should work fine.
Upvotes: 5