有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java根据jframe中的条件在特定区域上绘制颜色

我想通过在区域上标记颜色来指示站点的状态。Graphics2D类用于绘制颜色。它必须不断更新。我正在使用计时器,但它不工作。感谢您的帮助

import javax.swing.*;
import java.awt.*;
import redis.clients.jedis.Jedis;

public class Station1 {

    public Station1(){

        Gradient gradient = new Gradient();
        JFrame f =  new JFrame("Input Carousel"); 
        f.setLayout(new BorderLayout()); 

        JLabel label = new JLabel();
        ImageIcon icon = new ImageIcon(getClass().getResource("images/input carousel.jpg"));
        label.setIcon(icon);

        gradient.add(label);
        f.add(gradient);

        f.pack();    
        f.setResizable(false); 
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    }

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

    class Gradient extends JPanel{
    public Graphics2D g2D ;
    @Override
    public void paintComponent(Graphics g){

        g2D = (Graphics2D)g;
        AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
        g2D.setComposite(alphaComposite);

        new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                    try{
                        Jedis jedis = new Jedis("localhost");

                        if(jedis.get("b1").equals("1"))
                        {
                          g2D.setColor(Color.GREEN); 
                          g2D.fillRect(208, 172, 47, 75);
                        }
                        else if(jedis.get("b1").equals("e"))
                        {
                          g2D.setColor(Color.RED); 
                          g2D.fillRect(208, 172, 47, 75);
                        }

                        }
                        catch(Exception e)
                        {
                        }  
            }
        }).start();

     }

    }    

}

如果我在没有定时器的情况下运行代码,它就会工作。如果我用定时器,它不会画任何颜色。 请给我建议这个问题的解决方案


共 (1) 个答案

  1. # 1 楼答案

    该代码有几个明显的问题:

    1. 在绘制方法中启动计时器,该方法通常会被多次调用,而大多数调用都是您无法控制的
    2. 在绘制方法(以及Swing事件线程)中调用看起来可能会阻塞代码的代码。这可能会使您的代码完全无用,因为这可能会冻结gui

    建议:

    1. 创建计时器并将其启动一次,而不是在任何绘制方法中。也许可以在类的构造函数中执行此操作
    2. 计时器应该更改类的字段并调用repaint
    3. 然后,您的绘制方法应该使用这些字段的状态来决定要绘制的内容和位置
    4. 别忘了在重写中调用super.paintComponent(g);,通常在它的第一行
    5. 如果创建绝地意味着创建一段长时间运行的代码,那么在后台线程(如SwingWorker)中执行此操作
    6. 绘画方法仅用于绘画和绘画,您的代码应该尊重这一点

    例如,请查看下面的代码。请注意,我无法访问您的绝地职业(以及您使用绝地职业的原因),因此创建了一个“模拟”职业。此外,我没有访问您的图像,因此使用了此演示程序的公开图像。我也加快了你的计时器

    import javax.imageio.ImageIO;
    import javax.swing.*;
    import java.awt.*;
    // import redis.clients.jedis.Jedis;
    import java.awt.event.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.net.URL;
    
    public class Station1 {
        private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/"
                + "commons/thumb/f/f4/LINCOLN%2C_Abraham-President_%28BEP_engraved_portrait%29.jpg"
                + "/800px-LINCOLN%2C_Abraham-President_%28BEP_engraved_portrait%29.jpg";
    
        public Station1() {
            Gradient gradient = new Gradient();
            JFrame f = new JFrame("Input Carousel");
            f.setLayout(new BorderLayout());
    
            JLabel label = new JLabel();
    
            // ImageIcon icon = new ImageIcon(getClass().getResource("images/input carousel.jpg"));
    
            BufferedImage img = null;
            try {
                URL imgUrl = new URL(IMG_PATH);
                img = ImageIO.read(imgUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
            Icon icon = new ImageIcon(img);
    
            label.setIcon(icon);
    
            gradient.add(label);
            f.add(gradient);
    
            f.pack();
            f.setResizable(false);
            f.setVisible(true);
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new Station1();
                }
            });
        }
    
        @SuppressWarnings("serial")
        class Gradient extends JPanel {
            private JedisMock jedisMock = new JedisMock("localhost");
            private String jedisValue = "";
    
            public Gradient() {
                int timerDelay = 200;
                new Timer(timerDelay, new TimerListener()).start();
            }
    
            private class TimerListener implements ActionListener {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // may need to wrap this within a try/catch
                    jedisValue = jedisMock.get("b1");
                    repaint();
                }
            }
    
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2D = (Graphics2D) g;
                AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                        0.5f);
                g2D.setComposite(alphaComposite);
                if (jedisValue.equals("1")) {
                    g2D.setColor(Color.GREEN);
                    g2D.fillRect(208, 172, 47, 75);
                } else if (jedisValue.equals("e")) {
                    g2D.setColor(Color.RED);
                    g2D.fillRect(208, 172, 47, 75);
                }
            }
        }
    
    }
    

    public class JedisMock {
    
        private String host;
    
        public JedisMock(String host) {
            this.host = host;
        }
    
        public String getHost() {
            return host;
        }
    
        // method to mock your method
        public String get(String text) {
            double randomValue = Math.random();
            if (randomValue < 0.333) {
                return "1";
            } else if (randomValue < 0.667) {
                return "e";
            } else {
                return "";
            }
        }
    }