在半透明框架/面板/组件上重新涂漆。

我试图用OSX上的Java创build一个半透明的窗口,并添加一个JLabel

JLabel每秒更改其文本….

替代文字

但是,组件并没有很好的重绘。

我该如何解决这个问题?

我find了这些 文章 ,但我不知道如何解决它。

如果可能,请粘贴固定源代码,这是我的:

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

我有一些运气延伸JLabel和实现Icon以获得一个半透明的组件,我想要的方式工作。 您可以在此AlphaCompositeDemo中看到各种规则组合的结果。 下面的例子是100%白色在50%黑色之上。

附录:请注意,这个例子是如何在半透明的框架背景上,在清晰的屏幕背景上合成不透明文本的。

附录:这是一个使整个框架半透明的方法 。 不幸的是,它也使内容变暗。

图片

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

这个问题也可能与你从一个不是Event Dispatch Thread的线程设置JLabel的文本有关。

有两种方法可以解决这个问题。 没有testing你的问题,我会解决它通过使用javax.swing.Timer类,而不是java.util.Timer类。 javax.swing.Timer将确保在调度线程上触发事件。

所以(未经testing的代码):

 final ActionListener labelUpdater = new ActionListener() { private int i; @Override public final void actionPerformed(final ActionEvent event) { label.setText("Hola " + this.i++); } }; final javax.swing.Timer timer = new javax.swing.Timer(1000L, labelUpdater); 

解决这个问题的另一种方法是继续使用java.util.Timer但要确保使用EventQueue.invokeLater(Runnable)来确保在EDT上更新标签。

我不知道问题是否解决,但我解决了我的应用程序与“Frame.repaint();”

所以每一秒我的框架将被重新绘制,我的JLabel将与实际时间更新。

 /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package mreg; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JWindow; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** * * @author Manoj */ public class TranscluentWindow { public static void main(String[] args) { new TranscluentWindow(); } public TranscluentWindow() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } JWindow frame = new JWindow(); frame.setAlwaysOnTop(true); frame.addMouseListener(new MouseAdapter() { }); frame.setBackground(new Color(0,0,0,0)); frame.setContentPane(new TranslucentPane()); frame.add(new JLabel(new ImageIcon(ImageIO.read(getClass().getResource("/124742-high-school-collection/png/image_4.png"))))); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); new Thread(new Runnable() { public void run() { try { Thread.sleep(2500); } catch (InterruptedException ex) { } frame.dispose(); new loging().setVisible(true); } }).start(); } catch (IOException ex) { ex.printStackTrace(); } } }); } public class TranslucentPane extends JPanel { public TranslucentPane() { setOpaque(false); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setComposite(AlphaComposite.SrcOver.derive(0.0f)); g2d.setColor(getBackground()); g2d.fillRect(0, 0, getWidth(), getHeight()); } } }