2010-01-29 4 views
12

Я пытаюсь создать полупрозрачное окно с Java на OSX и добавить к нему JLabel.Повторно нанести на полупрозрачную рамку/панель/компонент.

Это JLabel меняет свой текст каждый второй ....

alt text

Однако компонент не перекрашивать хорошо.

Как я могу решить эту проблему?

Я нашел thesearticles, но я не могу понять, как его решить.

Если возможно, пожалуйста, вставьте исходный фиксирование код, вот мое:

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


    } 
} 
+1

Попробуйте сбросить фон в коде таймера или вызвать перерисовку на всей панели. Я думаю, что фон просто не знает, что его нужно перекрасить. – jjnguy

+0

Если это будет исправлено, я сделаю это ответом, но сейчас это просто догадка. – jjnguy

+3

+1 для включения логотипа SO. :-) – trashgod

ответ

14

Мне посчастливилось продлить JLabel и реализовать Icon, чтобы получить полупрозрачный компонент, работающий так, как я хочу. Вы можете увидеть результат различных комбинаций правил в этом AlphaCompositeDemo. Пример ниже: 100% белый на 50% черный.

Приложение: обратите внимание, как этот пример компонует непрозрачный текст на прозрачном заднем фоне на фоне полупрозрачной рамки.

Addendum: Здесь можно сделать whole frame translucent. К сожалению, он также уменьшает содержание.

image

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

+1 для добавления скриншота. Выглядит многообещающе. Единственное различие заключается в том, что текст не должен быть полупрозрачным, но непрозрачным (как этот снимок экрана в окнах), но с учетом текущего состояния моего кода, я думаю, это должно быть обходным путем для OSX. Я попробую завтра, когда у меня снова появится мой Mac. Спасибо. – OscarRyz

+0

О, вы не используете JLabel, а рисуете прямо на панели ... mmhhhh Я должен попробовать это. – OscarRyz

+0

Да, в какой-то момент вам нужно сделать композит с фоном кадра. Я обновлю, чтобы показать, как делать непрозрачный текст. – trashgod

4

Проблема также может быть связано с тем, что вы устанавливаете текст в JLabel «сек из потока, который не является поток событий.

Существует два способа решить эту проблему. Не тестируя вашу проблему, я бы решил ее, используя класс javax.swing.Timer, а не класс java.util.Timer. javax.swing.Timer обеспечит, чтобы события были запущены в потоке отправки.

So (непроверенный код):

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.

+0

В случае, если это не ясно, если вы делаете связанные с Swing вещи с помощью EDT, тогда вы получаете артефакты, подобные тем, которые вы испытываете - например, события рисования могут выходить из строя. jjnguy: повторная аттестация должна автоматически запускаться методом JLabel setText(); причина, по которой событие repaint() может работать здесь, потому что оно будет запланировано на EDT для последующего выполнения. Лучше убедиться, что начальный вызов setText() был сделан на EDT в первую очередь. –

+0

Я попытался переключая TimerTask к этому: timer.schedule (новый TimerTask() { INT I = 0; общественных недействительный запуск() { SwingUtilities.invokeLater (новый Runnable() { общественных недействительный запуск() { label.setText («Hola» + i ++); } }); } }, 0, 1000); И это не сработало. Sun Bug: http://bugs.sun.com/view_bug.do?bug_id=4297006 утверждает, что вам, возможно, придется переопределить paintComponent(), поскольку непрозрачность и полупрозрачность плохо взаимодействуют. – Kylar

+0

Yeap, я попытался на самом деле с 'SwingUtilities.invokeLater', который имеет тот же эффект (отправить сообщение в EDT) с точно такими же результатами. Я удаляю его перед публикацией, чтобы сделать код кратким. – OscarRyz

2

Я не знаю, если эта проблема будет решена, но я решил это в моем приложении с «Frame.repaint();»

Итак, каждую секунду мой кадр будет перекрашен, а мой JLabel будет обновляться с фактическим временем.

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

     } 

    } 



} 
+0

Вам следует избегать ответов только на код. – croxy