【问题标题】:how to paint jpanel every seconds with GradientPaint? [closed]如何使用 GradientPaint 每秒绘制 jpanel? [关闭]
【发布时间】:2012-12-07 06:50:37
【问题描述】:

我有两个类..类面板扩展了 JPanel,

还有另一个类每秒控制该 jpanel 的绘制..(我使用 swing.Timer)

我下面的代码失败了

到目前为止,我尝试了..

类面板扩展 JPanel :

@Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Control control = new Control(this,g);
        repaint();
    }

类控制:

public class Control implements ActionListener{

    private int XX=0;
    private int YY=0;

    private Graphics2D g2;
    private JPanel panel;

    Timer tim = new Timer(1000, this);


    public Control(JPanel el,Graphics g) {


        this.g2=(Graphics2D)g.create();
        this.panel=el;
        tim.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        XX++;
        YY++;

    /////////////////////
    //my priority 
        GradientPaint gp = new GradientPaint(XX, YY, Color.BLUE, panel.getWidth(), panel.getHeight(), Color.WHITE);
    //////////////////////

        g2.setPaint(gp);
        g2.fillRect(0, 0, panel.getWidth(), panel.getHeight());
        panel.repaint();
    }
}

我需要每秒钟改变一次 GradientPaint 的起点

然后每秒在jpanel中绘制一次

我该怎么办?

谢谢..

【问题讨论】:

  • 现在有什么问题?
  • @NikolayKuznetsov 我的代码失败..
  • 怎么会失败??解释更多

标签: java swing jpanel paintcomponent


【解决方案1】:

mKorbel 所说的一切......

  • 永远不要保留对绘制子系统传递给您的Graphics 上下文的引用。它在油漆周期之间变化
  • 永远不要调用repaint 或任何可能导致paintXxx 方法中的重绘请求的方法,这将导致重绘管理器在未来某个时间安排新的重绘并最终循环你的CPU 100%
  • Painting in AWT and Swing
  • Custom Painting in Swing
  • How to Swing Timer


public class TestPaintTimer {

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

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

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

        });
    }

    public class GradientPanel extends JPanel {

        private Color startColor = Color.RED;
        private Color endColor = Color.BLUE;
        private float progress = 0f;
        private float direction = 0.1f;

        public GradientPanel() {
            Timer timer = new Timer(125, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    progress += direction;
                    if (progress > 1f) {
                        direction *= -1;
                        progress = 1f;
                    } else if (progress < 0) {
                        direction *= -1;
                        progress = 0f;
                    }

                    startColor = calculateProgress(Color.RED, Color.BLUE, progress);
                    endColor = calculateProgress(Color.BLUE, Color.RED, progress);

                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            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();
            LinearGradientPaint lgp = new LinearGradientPaint(
                            new Point(0, 0),
                            new Point(0, getHeight()),
                            new float[]{0f, 1f},
                            new Color[]{startColor, endColor});
            g2d.setPaint(lgp);
            g2d.fill(new Rectangle(getWidth(), getHeight()));
            g2d.dispose();
        }

        public Color calculateProgress(Color startValue, Color endValue, float fraction) {
            int sRed = startValue.getRed();
            int sGreen = startValue.getGreen();
            int sBlue = startValue.getBlue();
            int sAlpha = startValue.getAlpha();

            int tRed = endValue.getRed();
            int tGreen = endValue.getGreen();
            int tBlue = endValue.getBlue();
            int tAlpha = endValue.getAlpha();

            int red = calculateProgress(sRed, tRed, fraction);
            int green = calculateProgress(sGreen, tGreen, fraction);
            int blue = calculateProgress(sBlue, tBlue, fraction);
            int alpha = calculateProgress(sAlpha, tAlpha, fraction);

            return new Color(red, green, blue, alpha);
        }

        public int calculateProgress(int startValue, int endValue, float fraction) {
            int value = 0;
            int distance = endValue - startValue;
//        value = Math.round((float)distance * fraction);
            value = (int) ((float) distance * fraction);
            value += startValue;

            return value;
        }

    }

}

【讨论】:

  • 非常感谢.. 真的很有帮助.. 十亿感谢代码.. 它拯救了我的日子/我的生命......
  • 顺便说一句..如果我有包含按钮的JFrame..然后当我点击它时。它将显示包含您的面板的 JDialog(来自您的代码)。然后我关闭那个JDialog ...计时器还在运行吗?我必须在关闭计时器之前停止它吗?还是可以放弃它?(让垃圾收集器完成这项工作?)
  • 是的,时间还在流逝。我不会依赖 GC 来接收它。如果需要,您可以将计时器设为类字段并提供启动和停止它的方法
【解决方案2】:
  1. 不要在paint/paintComponent(Control control = new Control(this,g);)中创建任何Object,在此/这些Object(s)之前准备好(您可以将元素放入数组中并且在paintComponent 里面只循环里面),这个想法在运行时创建了一堆对象,直到 NPE 变成了

  2. 你的代码设计错误,必须阅读Oracles 2D Graphics tutorial,tons examples here

  3. 必须为JPanel覆盖PreferredSize

  4. 你也可以创建BufferedImage

【讨论】:

  • 非常感谢..对我真的很有帮助..
【解决方案3】:

感谢 mKorbel 和 MadProgrammer,我终于可以解决它了..

这是我要找的代码..

响应 mKorbel & madProgrammer 的回答

   public class again extends JPanel{
    int xx=0;
    int xxMax;
    String go = "RIGHT";

    Timer t;
    ActionListener listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if(go.equals("RIGHT")){
                if(xx>=xxMax){go="LEFT";};
                xx += 10;

            }else if(go.equals("LEFT")){
                if(xx<=0){go="RIGHT";};
                xx -= 10;

            }
            repaint();
        }};

    public again() {
        t = new Timer(1, listener);
        t.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g.create();
        GradientPaint gp = new GradientPaint(0, 0, Color.black, xx, getHeight(), Color.WHITE);
        g2.setPaint(gp);
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.dispose();
        xxMax=getWidth();
    }
}


class Frame extends JFrame{

    public Frame(){
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        add(new again());
        setVisible(true);
    }

    public static void main (String[]args){
        new Frame().setExtendedState(MAXIMIZED_BOTH);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 2022-01-24
    • 2016-03-20
    • 2014-12-03
    相关资源
    最近更新 更多