简体   繁体   English

如何停止repaint()闪烁

[英]How to stop repaint() flickering

I am trying to make a program to java and i have the common problem with flickering. 我试图制作一个程序到Java,我有闪烁的常见问题。 I have try many things to eliminate but all the same. 我已经尝试了很多消除的方法,但是都是一样的。 while the oval that i paint is moving the japplet is flickering. 当我画的椭圆移动时,小灯在闪烁。 i need your help to solve this problem. 我需要您的帮助来解决这个问题。 here is my code: 这是我的代码:

import java.awt.Color;

public class all extends JApplet implements Runnable {

    double x=0;
    double y=0;
    int m=0;
    int n=0;
    int f=30;
    int μ=0;
    Thread kinisi;
    JPanel panel;
    JFrame frame;
    private boolean running = false;
    private JTextField textField1;
    private JTextField textField2;
    Image backGround;
    JPanel panel_3;
    Image bf = createImage(m, n);
    private Graphics doubleg;
    private Image i;

    public void init() {
        this.setSize(800, 700);
    }

    public all() {
        getContentPane().setLayout(null);

        JButton btnNewButton = new JButton("Start");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) { 
                String b=textField2.getText();
                String z =textField1.getText();
                if (textField1.getText().equals("") || 
                    textField2.getText().equals("")){
                    JOptionPane.showMessageDialog(
                        new JFrame(),
                        "Δωστε τιμή για το φ και το μ!",
                        "ERROR",JOptionPane.ERROR_MESSAGE);
        } else{
                f = Integer.parseInt(b);
                μ = Integer.parseInt(z); 
                Start();    }
            }
        });
        btnNewButton.setBounds(469, 168, 89, 23);
        getContentPane().add(btnNewButton);

        JButton btnStop = new JButton("Pause");
        btnStop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pause();
            }
        });
        btnStop.setBounds(588, 168, 89, 23);
        getContentPane().add(btnStop);

        JButton btnReset = new JButton("Reset");
        btnReset.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Reset();
            }
        });
        btnReset.setBounds(701, 168, 89, 23);
        getContentPane().add(btnReset);

        JLabel label = new JLabel("\u03BC");
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setBounds(549, 63, 46, 14);
        getContentPane().add(label);

        textField1 = new JTextField();
        textField1.setBounds(529, 101, 86, 20);
        getContentPane().add(textField1);
        textField1.setColumns(10);

        JLabel label_1 = new JLabel("\u03C6");
        label_1.setHorizontalAlignment(SwingConstants.CENTER);
        label_1.setBounds(681, 63, 46, 14);
        getContentPane().add(label_1);

        textField2 = new JTextField();
        textField2.setBounds(667, 101, 86, 20);
        getContentPane().add(textField2);
        textField2.setColumns(10);

        JButton btnNewButton_1 = new JButton("");
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                JOptionPane.showMessageDialog(
                    new JFrame(),
                    "Οδηγίες προγράμματος","Οδηγίες",
                    JOptionPane.INFORMATION_MESSAGE);
                }
        });
        btnNewButton_1.setIcon(
            new ImageIcon(all.class.getResource("/Images/info.png")));
        btnNewButton_1.setBounds(732, 5, 39, 35);
        getContentPane().add(btnNewButton_1);

        JLabel label_2 = new JLabel("");
        label_2.setIcon(
            new ImageIcon(all.class.getResource("/Images/earth.jpg")));
        label_2.setBounds(-20, 0, 820, 361);
        getContentPane().add(label_2);

        JPanel panel_1 = new JPanel();
        panel_1.setBorder(
            new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
        panel_1.setBounds(10, 372, 369, 290);
        getContentPane().add(panel_1);

        JPanel panel_2 = new JPanel();
        panel_2.setBorder(
            new BevelBorder(BevelBorder.LOWERED, null, null, null, null));
        panel_2.setBounds(408, 372, 369, 290);
        getContentPane().add(panel_2);
    }

    public void paint(Graphics g){
        super.paint(g);
        g.drawLine(0,f,350,200);
        g.drawLine(0,200,350,200);  
        g.drawOval(m,n,40,40);
        Color brown=new Color(137,66,0);
        g.setColor(brown);
        g.fillOval(m, n, 40, 40);
        //Graphics2D g2d = (Graphics2D) g;
        g.drawLine(460,400,460,650);
        g.drawLine(20, 620, 350, 620);
        g.drawLine(50,400,50,650);
        g.drawLine(430, 620, 760, 620); 
    }

    public void Start() {
        kinisi = new Thread(this);
        kinisi.start();
        running = true; 
    }

    public void run() {
        while (running) {
            if (x < 340){
                double l = 200-f;
                double k = l/350;
                double y=k*x+f-30;
                x= x+1;
                m = (int) x;
                n = (int) y;
                repaint();
                try {
                    Thread.sleep(μ);  
                } catch (InterruptedException ie) {}
            }
        }
    }

    public void update(Graphics g) {
        if(i==null){
            i=createImage(800,700);
            doubleg = i.getGraphics();
        }
        doubleg.setColor(getBackground());
        doubleg.fillRect(0,0,800,700);
        doubleg.setColor(getForeground());
        paint(doubleg);
        g.drawImage(i,0,0,this);
    }

    public void paint1(Graphics g){
        g.drawLine(0, f ,350, 200);
        g.drawOval(m, n, 40, 40);
        Color brown=new Color(137,66,0);
        g.setColor(brown);
        g.fillOval(m, n, 40, 40);
    }

    public void pause() {
        if (kinisi != null) {
            running = false;
        }
    }

    public boolean Reset() {
        if (kinisi != null) {
            running = false;
            kinisi.interrupt();
            kinisi = null;
            x=0;
            y=0;
            f=30;
            m=0;
            n=0;
            repaint();
            textField1.setText("");
            textField2.setText("");
        }
        Graphics g = getGraphics();
        g.drawOval(m,n,40,40);
        Color brown=new Color(137,66,0);
        g.setColor(brown);
        g.fillOval(m, n, 40, 40);
        return false;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("FISIKI");
        frame.getContentPane().add(new all());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 700);
        frame.setVisible(true); 
        frame.setResizable(false);
    }
}

Thank you very much and sorry for my english are not very good! 非常感谢,对不起,我的英语不好!

There are a number of things that jump out at me. 有很多事情让我惊讶。

  • You're extending from JApplet , but are adding it to a JFrame 您从JApplet扩展而来,但将其添加到JFrame
  • You're mixing components with you custom painting 您正在将组件与自定义绘画混合
  • Not using layout managers. 不使用布局管理器。
  • Using getGraphics . 使用getGraphics

Firstly... 首先...

You should never override paint of a top level container (like JApplet ). 您永远不应覆盖顶级容器(如JApplet )的paint There are many reasons and you've found one. 原因有很多,您已经找到了一个。 Top level containers are not double buffered. 顶级容器不是双缓冲的。 Instead, you should be creating a custom component (by extending something like JPanel ) and overriding it's paintComponent method... 相反,您应该创建一个自定义组件(通过扩展JPanel东西)并覆盖它的paintComponent方法...

Secondly 其次

Decided how you application is going to be. 决定您的应用程序的状态。 Is it an applet or application? 它是applet还是应用程序? If you follow the first point, then it really doesn't matter, as you only simply need to add the panel to the top level container. 如果您遵循第一个要点,那实际上就没有关系,因为您只需要将面板添加到顶层容器即可。

Thirdly 第三

I would create a panel that did the custom painting. 我将创建一个执行自定义绘画的面板。 Then I would create separate containers for all the fields and other parts of the application. 然后,我将为应用程序的所有字段和其他部分创建单独的容器。 This will allow you to separate the areas of responsibility. 这将使您可以区分责任范围。 It would also allow you to use layout managers ;) 它还将允许您使用布局管理器;)

Fourthly 第四

Use layout managers. 使用布局管理器。 The layout manager API has being designed to solve one of this most annoying aspects of GUI design, you're asking for a lot of trouble and work you decided to discard it - IMHO. 布局管理器API旨在解决GUI设计的这一最烦人的方面之一,您遇到了很多麻烦,因此您决定放弃它-IMHO。

Fifthly 第五

getGraphics should never be used. 永远不要使用getGraphics Apart from the fact that it can return null , it is only a snap shot of what is currently on the screen. 除了它可以返回null ,它只是屏幕上当前内容的快照。 As soon as the RepaintManager decides to perform a repaint, anything rendered to it will be lost. 一旦RepaintManager决定执行重新绘制,呈现给它的所有内容都会丢失。 You should use paintComponent to update the state of your custom pane. 您应该使用paintComponent更新自定义窗格的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM