在半透明框架/面板/组件上重新上漆. [英] Re-paint on translucent frame/panel/component.

查看:19
本文介绍了在半透明框架/面板/组件上重新上漆.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 OSX 上使用 Java 创建一个半透明窗口并向其添加 JLabel.

这个 JLabel 每秒都会改变它的文本....

但是组件不能很好地重新绘制.

我该如何解决这个问题?

我找到了

import java.awt.AlphaComposite;导入 java.awt.Color;导入 java.awt.Dimension;导入 java.awt.EventQueue;导入 java.awt.Font;导入 java.awt.FontMetrics;导入 java.awt.Graphics;导入 java.awt.Graphics2D;导入 java.awt.RenderingHints;导入 java.awt.event.ActionEvent;导入 java.awt.event.ActionListener;导入 java.awt.image.BufferedImage;导入 java.text.SimpleDateFormat;导入 java.util.Date;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.Timer;公共类半透明扩展 JPanel 实现 ActionListener {私有静态最终整数 W = 300;私有静态最终 int H = 100;私有静态最终字体字体=新字体(衬线",Font.PLAIN,48);私有静态最终 SimpleDateFormat df =new SimpleDateFormat("HH:mm:ss");私人最终日期现在=新日期();private final Timer timer = new Timer(1000, this);私有 BufferedImage 时间;私有 Graphics2D timeG;公共半透明(){超级(真);this.setPreferredSize(new Dimension(W, H));定时器开始();}@覆盖受保护的无效paintComponent(图形g){Graphics2D g2d = (Graphics2D) g;g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);int w = this.getWidth();int h = this.getHeight();g2d.setComposite(AlphaComposite.Clear);g2d.fillRect(0, 0, w, h);g2d.setComposite(AlphaComposite.Src);g2d.setPaint(g2d.getBackground());g2d.fillRect(0, 0, w, h);渲染时间(g2d);int w2 = time.getWidth()/2;int h2 = time.getHeight()/2;g2d.setComposite(AlphaComposite.SrcOver);g2d.drawImage(time, w/2 - w2, h/2 - h2, null);}私有无效渲染时间(Graphics2D g2d){g2d.setFont(字体);字符串 s = df.format(现在);FontMetrics fm = g2d.getFontMetrics();int w = fm.stringWidth(s);int h = fm.getHeight();if (time == null && timeG == null) {时间 = 新的 BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);timeG = time.createGraphics();timeG.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);timeG.setFont(字体);}timeG.setComposite(AlphaComposite.Clear);timeG.fillRect(0, 0, w, h);timeG.setComposite(AlphaComposite.Src);timeG.setPaint(Color.green);timeG.drawString(s, 0, fm.getAscent());}私有静态无效创建(){JFrame f = new JFrame();f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setBackground(新颜色(0f, 0f, 0f, 0.3f));f.setUndecorated(true);f.添加(新半透明());f.pack();f.setLocationRelativeTo(null);f.setVisible(true);}@覆盖public void actionPerformed(ActionEvent e) {now.setTime(System.currentTimeMillis());this.repaint();}公共静态无效主(字符串 [] args){EventQueue.invokeLater(new Runnable() {@覆盖公共无效运行(){创建();}});}}

I'm trying to create a translucent window with Java on OSX and add a JLabel to it.

This JLabel changes its text every second....

However the component is not repainting well.

How can I solve this problem?

I've found the these articles, but I can't figure out how to solve it.

If possible, please paste the fixing source code, here's mine:

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.Color;
import java.awt.Font;
import java.util.Timer;
import java.util.TimerTask;

public class Translucent {
    public static void main( String [] args ) {

        JFrame frame = new JFrame();

        frame.setBackground( new Color( 0.0f,0.0f,0.0f,0.3f));

        final JLabel label =  new JLabel("Hola");
        label.setFont( new Font( label.getFont().getFamily(), Font.PLAIN, 46 ) );
        label.setForeground( Color.white );

        frame.add( label );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );

        Timer timer = new Timer();
        timer.schedule( new TimerTask(){
            int i = 0;
            public void run() {
                label.setText("Hola "+ i++ );
            }
        }, 0, 1000 );


    }   
}

解决方案

I've had some luck extending JLabel and implementing Icon to get a translucent component working the way I want. You can see the result of various rule combinations in this AlphaCompositeDemo. The example below is 100% white atop 50% black.

Addendum: Note how this example composites opaque text on a clear offscreen background over the translucent frame background.

Addendum: Here's a way to make the whole frame translucent. Unfortunately, it dims the content, too.

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Translucent extends JPanel implements ActionListener {

    private static final int W = 300;
    private static final int H = 100;
    private static final Font font =
        new Font("Serif", Font.PLAIN, 48);
    private static final SimpleDateFormat df =
        new SimpleDateFormat("HH:mm:ss");
    private final Date now = new Date();
    private final Timer timer = new Timer(1000, this);
    private BufferedImage time;
    private Graphics2D timeG;

    public Translucent() {
        super(true);
        this.setPreferredSize(new Dimension(W, H));
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        int w = this.getWidth();
        int h = this.getHeight();
        g2d.setComposite(AlphaComposite.Clear);
        g2d.fillRect(0, 0, w, h);
        g2d.setComposite(AlphaComposite.Src);
        g2d.setPaint(g2d.getBackground());
        g2d.fillRect(0, 0, w, h);
        renderTime(g2d);
        int w2 = time.getWidth() / 2;
        int h2 = time.getHeight() / 2;
        g2d.setComposite(AlphaComposite.SrcOver);
        g2d.drawImage(time, w / 2 - w2, h / 2 - h2, null);
    }

    private void renderTime(Graphics2D g2d) {
        g2d.setFont(font);
        String s = df.format(now);
        FontMetrics fm = g2d.getFontMetrics();
        int w = fm.stringWidth(s);
        int h = fm.getHeight();
        if (time == null && timeG == null) {
            time = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            timeG = time.createGraphics();
            timeG.setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            timeG.setFont(font);
        }
        timeG.setComposite(AlphaComposite.Clear);
        timeG.fillRect(0, 0, w, h);
        timeG.setComposite(AlphaComposite.Src);
        timeG.setPaint(Color.green);
        timeG.drawString(s, 0, fm.getAscent());
    }

    private static void create() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setBackground(new Color(0f, 0f, 0f, 0.3f));
        f.setUndecorated(true);
        f.add(new Translucent());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        now.setTime(System.currentTimeMillis());
        this.repaint();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                create();
            }
        });
    }
}

这篇关于在半透明框架/面板/组件上重新上漆.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆