【问题标题】:Thread help. Paint [closed]线程帮助。油漆[关闭]
【发布时间】:2013-09-23 03:17:47
【问题描述】:

除了要求删除内容的注释行之外,有人可以帮我解决问题吗?谢谢!

public class ex1011c extends JApplet implements ActionListener
{
        // get rid of all winkbutton code

    JButton winkbutton = new JButton("Wink At You");
    boolean wink = false, first = true;
    Container c;

    public void init()
    {
        c = getContentPane();
        c.setLayout(new FlowLayout());
        c.setBackground(Color.blue);
        winkbutton.setForeground(Color.cyan);
        c.add(winkbutton);
        winkbutton.addActionListener(this);
    }

        // get rid of actionPerformed

    public void actionPerformed(ActionEvent e)
    {
        wink = !wink;
        repaint();
    }

    public void paint(Graphics g)
    {
        /* if first time, draw the face and non winking eye,
            set first to false */

        super.paint(g);
        g.setColor(Color.yellow);
        g.fillOval(50, 50, 100, 100);
        g.setColor(Color.black);
        g.fillOval(85, 80, 10, 20);

        /* cover just the eye that winks (if winking or not, but do not
         cover anything else), switch the wink boolean */

        // draw the full eye or winking eye

        if (wink)
            g.fillOval(105, 88, 10, 5);
        else
            g.fillOval(105, 80, 10, 20);

        // go to sleep for a second

        // call repaint
    }

        // override update to lesson flicker

}

【问题讨论】:

  • 不要将逻辑放在绘画事件中。相反,使用计时器并存储状态。
  • @raffian 在整个代码中都有关于要做的事情的注释行。我被他们困住了。我会很感激任何帮助
  • “我被他们困住了。” 你看过哪些教程?你试过什么?你究竟在哪里卡住了?请注意,一个好的 SO 问题应该有一个问题,该问题具有一个或多个答案。您发布的内容相当于“购物清单”。

标签: java multithreading swing java-2d japplet


【解决方案1】:

简单,不要休眠/暂停/阻塞或以其他方式阻碍事件调度线程。

除其他外,EDT 负责处理绘制请求,任何阻止它运行的东西(如Thread.sleep)都会阻止它更新屏幕。

请记住,仅仅因为您在 Graphics 上下文中绘制了一些东西,并不意味着它会被渲染到输出中。

改为使用javax.swing.Timer

查看Concurrency in SwingPerforming Custom PaintingPainting in AWT and Swing 了解更多详情。

我还强烈建议您不要覆盖顶级容器的任何 paint 方法,例如 JApplet。相反,请使用 JPanel 之类的东西并覆盖它的 paintComponent 方法。

除了可饮用性之外,您还可以获得顶级容器所没有的双重缓冲的好处...

例如...

举个简单的例子

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Blinky {

    public static void main(String[] args) {
        new Blinky();
    }

    public Blinky() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BlinkPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class BlinkPane extends JPanel {

        private boolean wink;

        public BlinkPane() {
            Timer timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    wink = !wink;
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - 10) / 2;
            int eyeHeight = 20;
            if (wink) {
                eyeHeight = 5;
            }
            int y = (getWidth() - eyeHeight) / 2;
            g.fillOval(x, y, 10, eyeHeight);
            g2d.dispose();
        }
    }
}

【讨论】:

  • 如何减少闪烁?
  • 使用JPanel(覆盖它的paintComponent方法,你在那里自定义绘画),添加到你的小程序,闪烁消失...
猜你喜欢
  • 2014-06-04
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
相关资源
最近更新 更多