Java Swing Graphics - 为什么第一次渲染不能按预期工作?

时间:2012-03-05 20:19:33

标签: java swing

我有一个奇怪的问题,可能源于对Swing如何工作缺乏了解。当程序启动后的第一次,当我按下其中一个字母键时,我尝试重新将面板渲染到一个窗口框架中,在面板再次变为白色之前,在面板上非常短暂地绘制有问题的字符

在随后的击键中,程序然后按预期运行:面板使用与按下的键关联的字符重新渲染。

由于字符IS在第一个键击上绘制,因此它之后立即消失的事实必然意味着面板呈现为AGAIN,从而覆盖了之前的内容。

以下是代码:

// 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) {}
}
}
编辑:谢谢你的回答。现在我明白了绘画应该如何在Swing中起作用。

如果我需要面板重绘,我只需调用repaint()即可使系统调用paintComponent(Graphics g)。因此,无论我想画什么,我都把它放在一个被覆盖的paintComponent()方法中。永远不会直接调用paintComponent()。仅使用repaint()

1 个答案:

答案 0 :(得分:5)

您不应该直接调用paintPanel。 swing管理绘画本身。而不是你应该做以下事情:

  • 覆盖JComponent.paintComponent(Graphics g);它应该使用一个字段来检索被按下的字符
  • 按键,您应设置字段并调用JComponent.repaint();

这应该可以正常工作。