简体   繁体   English

为什么我的重绘不起作用?

[英]Why doesn't my repaint work?

I'm stuck with a problem considering my Display class, which extends Canvas.考虑到我的显示器 class 扩展了 Canvas,我遇到了一个问题。 A single thread is running within the very same class.一个线程在同一个 class 中运行。 In this thread, the repaint method is called.在这个线程中,调用了 repaint 方法。 However, while the thread works fine, the paint method is never called!然而,虽然线程工作正常,但从不调用paint方法!

Here's my code (I left out everything unrelated):这是我的代码(我省略了所有不相关的内容):

package display;

public final class Display extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;

private Frame frame;

private GraphicsEnvironment ge;
private GraphicsDevice gd;

public BDisplay() {     
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    gd = ge.getDefaultScreenDevice();

    frame = new Frame();

    //frame.setUndecorated(true);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    frame.setVisible(true);

    frame.add(this);

    frame.setLayout(null);

    //gd.setFullScreenWindow(frame);
}

@Override
public final void paint(Graphics g) {
    //THIS METHOD IS NEVER CALLED

    System.out.println("Paint method was called!");
    super.paint(g);

    //...
}

@Override
public synchronized void run() {
    while (isRunning()) {
        //THIS LOOP WORKS FINE.
        this.repaint();
    }
}
}

It has nothing to do with some missing functions like isRunning().它与一些缺少的函数(如 isRunning())无关。 They exist, i just left those out.它们存在,我只是把它们排除在外。

I never stumbled across a problem like this before, although I haven't done anything with SWING or AWT for some time now.我以前从未偶然发现过这样的问题,尽管我已经有一段时间没有对 SWING 或 AWT 做过任何事情了。

Can anyone help?任何人都可以帮忙吗?

The thread loop works fine, but the repaint just doesn't seem to get scheduled...线程循环工作正常,但重绘似乎没有安排......

You're realizing the JFrame before you add the component (ie Canvas , and previously JPanel ).在添加组件之前,您正在实现JFrame (即Canvas和之前的JPanel )。

Try this尝试这个

public BDisplay() {     
    ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    gd = ge.getDefaultScreenDevice();

    frame = new Frame();
    frame.setResizable(false);
    frame.add(this);
    //frame.setLayout(null); // Why are you using a null layout?
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

EDIT编辑

By the way, I'd recommend using a JPanel instead of a Canvas since it's not recommended that you mix heavy and light components.顺便说一句,我建议使用JPanel而不是Canvas ,因为不建议您混合使用重型和轻型组件。 For more detail, see Mixing heavy and light components .有关更多详细信息,请参阅混合重型和轻型组件

and now???现在??? by using javax.swing.Timer通过使用javax.swing.Timer

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class AnimationJPanel extends JPanel {

    private static final long serialVersionUID = 1L;
    private int cx = 0;
    private int cy = 150;
    private int cw = 20;
    private int ch = 20;
    private int xinc = 1;
    private int yinc = 1;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                AnimationJPanel panel = new AnimationJPanel();
                panel.setPreferredSize(new Dimension(400, 300));
                panel.animate();
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(panel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public AnimationJPanel() {
        setLayout(new BorderLayout());
        JLabel label = new JLabel("This is an AnimationJPanel");
        label.setForeground(Color.RED);
        label.setHorizontalAlignment(SwingConstants.CENTER);
        add(label);
        setBackground(Color.BLACK);
        setForeground(Color.RED);
        setOpaque(true);
    }

    public void animate() {
        new Timer(15, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Rectangle oldCircle = new Rectangle(cx - 1, cy - 1, cw + 2, ch + 2);
                cx += xinc;
                cy += yinc;
                if (cx >= getWidth() - cw || cx <= 0) {
                    xinc *= -1;
                }
                if (cy >= getHeight() - ch || cy <= 0) {
                    yinc *= -1;
                }
                repaint(oldCircle);
                repaint(cx - 1, cy - 1, cw + 2, ch + 2);
            }
        }).start();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawOval(cx, cy, cw, ch);
    }
}

or或者

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class AnimationBackground {

    public AnimationBackground() {
        Random random = new Random();
        JFrame frame = new JFrame("Animation Background");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        final MyJPanel panel = new MyJPanel();
        panel.setBackground(Color.BLACK);
        for (int i = 0; i < 50; i++) {
            Star star = new Star(new Point(random.nextInt(490), random.nextInt(490)));
            star.setColor(new Color(100 + random.nextInt(155), 100 + random.nextInt(155), 100 + random.nextInt(155)));
            star.setxIncr(-3 + random.nextInt(7));
            star.setyIncr(-3 + random.nextInt(7));
            panel.add(star);
        }
        panel.setLayout(new GridLayout(10, 1));
        JLabel label = new JLabel("This is a Starry background.", JLabel.CENTER);
        label.setForeground(Color.WHITE);
        panel.add(label);
        JPanel stopPanel = new JPanel();
        stopPanel.setOpaque(false);
        stopPanel.add(new JButton(new AbstractAction("Stop this madness!!") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                panel.stopAnimation();
            }
        }));
        panel.add(stopPanel);
        JPanel startPanel = new JPanel();
        startPanel.setOpaque(false);
        startPanel.add(new JButton(new AbstractAction("Start moving...") {

            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent e) {
                panel.startAnimation();
            }
        }));
        panel.add(startPanel);
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                AnimationBackground animationBackground = new AnimationBackground();
            }
        });
    }

    class Star extends Polygon {

        private static final long serialVersionUID = 1L;
        private Point location = null;
        private Color color = Color.YELLOW;
        private int xIncr, yIncr;
        static final int WIDTH = 500, HEIGHT = 500;

        Star(Point location) {
            int x = location.x;
            int y = location.y;
            this.location = location;
            this.addPoint(x, y + 8);
            this.addPoint(x + 8, y + 8);
            this.addPoint(x + 11, y);
            this.addPoint(x + 14, y + 8);
            this.addPoint(x + 22, y + 8);
            this.addPoint(x + 17, y + 12);
            this.addPoint(x + 21, y + 20);
            this.addPoint(x + 11, y + 14);
            this.addPoint(x + 3, y + 20);
            this.addPoint(x + 6, y + 12);
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public void move() {
            if (location.x < 0 || location.x > WIDTH) {
                xIncr = -xIncr;
            }
            if (location.y < 0 || location.y > WIDTH) {
                yIncr = -yIncr;
            }
            translate(xIncr, yIncr);
            location.setLocation(location.x + xIncr, location.y + yIncr);
        }

        public void setxIncr(int xIncr) {
            this.xIncr = xIncr;
        }

        public void setyIncr(int yIncr) {
            this.yIncr = yIncr;
        }

        public Color getColor() {
            return color;
        }
    }

    class MyJPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        private ArrayList<Star> stars = new ArrayList<Star>();
        private Timer timer = new Timer(20, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (Star star : stars) {
                    star.move();
                }
                repaint();
            }
        });

        public void stopAnimation() {
            if (timer.isRunning()) {
                timer.stop();
            }
        }

        public void startAnimation() {
            if (!timer.isRunning()) {
                timer.start();
            }
        }

        @Override
        public void addNotify() {
            super.addNotify();
            timer.start();
        }

        @Override
        public void removeNotify() {
            super.removeNotify();
            timer.stop();
        }

        MyJPanel() {
            this.setPreferredSize(new Dimension(512, 512));
        }

        public void add(Star star) {
            stars.add(star);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            for (Star star : stars) {
                g.setColor(star.getColor());
                g.fillPolygon(star);
            }
        }
    }
}

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

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