Rifinire su canvasio / pannello / componente trasshiny.

Sto provando a creare una finestra traslucida con Java su OSX e ad aggiungere una JLabel .

Questa JLabel cambia il suo testo ogni secondo ….

alt text

Tuttavia, il componente non sta ridipingendo bene.

Come posso risolvere questo problema?

Ho trovato questi articoli , ma non riesco a capire come risolverlo.

Se ansible, si prega di incollare il codice sorgente di fissaggio, ecco la mia:

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

Ho avuto un po ‘di fortuna nell’estendere JLabel e implementare Icon per ottenere un componente trasshiny che funziona come voglio io. Puoi vedere il risultato di varie combinazioni di regole in questo AlphaCompositeDemo . L’esempio sotto è 100% bianco in cima al 50% nero.

Addendum: si noti come questo esempio componga testo opaco su uno sfondo fuori schermo chiaro sullo sfondo del fotogramma trasshiny.

Addendum: ecco un modo per rendere l’ intera struttura traslucida . Sfortunatamente, attenua anche il contenuto.

Immagine

 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 actionPerformsd(ActionEvent e) { now.setTime(System.currentTimeMillis()); this.repaint(); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { create(); } }); } } 

Il problema potrebbe anche essere dovuto al fatto che stai impostando il testo di JLabel da un thread che non è il thread di JLabel eventi.

Ci sono due modi per risolvere questo. Senza testare il tuo problema, lo risolveremo usando la class javax.swing.Timer , invece della class java.util.Timer . javax.swing.Timer garantirà che gli eventi vengano triggersti ​​nel thread di invio.

Quindi (codice non testato):

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

L’altro modo per risolverlo è continuare a utilizzare java.util.Timer ma per assicurarsi di utilizzare EventQueue.invokeLater(Runnable) per assicurarsi che gli aggiornamenti all’etichetta avvengano EventQueue.invokeLater(Runnable) .

Non so se il problema è risolto, ma l’ho risolto nella mia applicazione con un “Frame.repaint ();”

Quindi ogni secondo il mio Frame sarà ridipinto e il mio JLabel sarà aggiornato con il tempo reale.

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