重绘时文本字段变形

时间:2016-01-23 01:45:07

标签: java swing graphics components repaint

我有一个非常简单的JFrame(它只包含一个文本字段和我绘制的很多东西),但每当调用repaint()时,文本字段都会发生变化。我很确定它是重绘(),因为即使我将帧从一个监视器拖到下一个监视器以及每次在代码中调用它时都会发生这种情况。

当我运行程序时它开始很好:

但是,每当调用repaint()时,都会发生这种情况:

如果我开始在字段中输入,其余的会立即弹回并正常工作。最终,我的最终目标是将我的框架的大部分重置为paintComponent()中绘制的内容,同时仍然可以看到文本字段。

我对图形和绘画比较陌生,非常感谢任何帮助!

修改

在创建SSCCE时,我发现文本字段的问题是由我的paintComponent方法中的Graphics2D方法旋转引起的。我不知道为什么会这样,但我可以解决它,并认为问题已经解决了。

现在,我遇到了一个新问题:我的paintComponent方法被调用太多次了。下面是这个问题的SSCCE,我希望事情发生的顺序是:

  1. 调用paintComponent()
  2. (按下按钮时)调用repaint()
  3. (按下按钮时,重绘后)调用paintStuff()
  4. 这一切都发生了,但是之后paintComponent以某种方式被调用,删除了paintStuff()绘制的所有内容。

    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class tester extends JFrame {
    
        private JPanel contentPane;
        private JButton button;
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        tester frame = new tester();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        /**
         * Create the frame.
         */
        public tester() {
            setBounds(100, 100, 450, 300);
            setResizable(false);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            contentPane = new JPanel(){
                public void paintComponent(Graphics g1) {
                    System.out.println("draw rectangle - should be first");
                    super.paintComponent(g1);
    
                    g1.drawRect(50,50,50,50);
                }
            };
            contentPane.setLayout(null);
            setContentPane(contentPane);
    
            button = new JButton("Click me!");
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("repaint - should be second");
                    repaint();
    
                    paintStuff(contentPane.getGraphics());
                }
            });
            button.setBounds(10, 11, 95, 20);
            contentPane.add(button);
        }
    
        public void paintStuff(Graphics g){
            System.out.println("draw circle - should be last");
            g.drawOval(100,100,10,10);
        }
    
    }
    

1 个答案:

答案 0 :(得分:2)

paintStuff(contentPane.getGraphics());

不,不要使用getGraphics()方法进行绘画。要重新绘制组件,只需使用:

contentPane.repaint();

然后将drawOval(...)语句移动到paintComponent()方法。

如果要有条件地绘制椭圆,则需要为自定义绘画创建一个布尔属性。然后代码看起来像:

super.paintComponent(g1);

g1.drawRect(50,50,50,50);

if (drawOval)
    g1.drawOval(100,100,10,10);    

然后在你的课堂上你会创建一个方法,如:

public void setDrawOval(Boolean drawOval)
{
    this.drawOval = drawOval;
    repaint();
}

所以在ActionListener中你只需使用:

contentPane.setDrawOval(true);