Java Swing Graphics - Почему первый рендеринг не работает должным образом? - PullRequest
2 голосов
/ 06 марта 2012

У меня странная проблема, которая, вероятно, связана с непониманием того, как работает Swing.Когда впервые с момента запуска программы я пытаюсь заново визуализировать панель внутри оконного фрейма, как только я нажимаю одну из буквенных символов, соответствующий символ очень быстро закрашивается на панели, прежде чем панель снова станет белой..

При последующих нажатиях клавиш программа ведет себя так, как и ожидалось: панель повторно визуализируется с символом, связанным с нажатой клавишей.

Поскольку символ отображается на первом нажатии клавиши,тот факт, что он сразу же исчезает, должен означать, что панель СДЕЛАНА СНОВА, таким образом, переопределяя предыдущее содержимое.

Вот код:

// 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 Ответ

5 голосов
/ 06 марта 2012

Вы не должны вызывать paintPanel напрямую.Свинг управляет живописью сам.Вместо этого вы должны сделать следующее:

  • Переопределить JComponent.paintComponent (Graphics g);Для извлечения нажатого символа следует использовать поле
  • . При нажатии клавиши вы должны установить поле и вызвать JComponent.repaint ();

Это должно работать нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...