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

时间:2018-12-25 11:31:18

标签: java swing graphics

我想通过在区域上标记颜色来指示电台的状态。 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 个答案:

答案 0 :(得分:0)

该代码存在几个明显的问题:

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

建议:

  1. 创建计时器并一次启动它,而不是在任何绘画方法中。也许可以在类的构造函数中完成
  2. 计时器应更改类的字段并调用repaint
  3. 然后,您的绘画方法应使用这些字段的状态来决定要绘画的内容和位置
  4. 不要忘记在覆盖中调用# lib/foo.rb module Foo class << self attr_accessor :models end self.models = [] class Engine < Rails::Engine initializer 'foo.eager_load_models' do |app| unless app.config.eager_load models_load_path = File.join(Rails.root, 'app', 'models') # copied from https://apidock.com/rails/Rails/Engine/eager_load%21/class matcher = /\A#{Regexp.escape(models_load_path.to_s)}\/(.*)\.rb\Z/ Dir.glob("#{models_load_path}/**/*.rb").sort.each do |file| app.require_dependency file.sub(matcher, '\1') end end end end module Model def acts_as_foo Foo.models << self end end end ActiveSupport.on_load(:active_record) do extend Foo::Model end ,通常是在其第一行。
  5. 如果创建Jedis意味着要创建长时间运行的代码,请在诸如SwingWorker之类的后台线程中执行此操作
  6. 一种绘画方法仅适用于绘画,您的代码应尊重这一点。

例如,请查看下面的代码。请注意,我无权访问您的Jedis类(也不知道为什么要使用它),因此创建了“模拟”类。另外,我无权访问您的图片,因此该演示程序使用了公开可用的图片。我还加快了您的计时器。

super.paintComponent(g);

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);
            }
        }
    }

}