2010-01-29 23 views
12

Tôi đang cố gắng tạo một cửa sổ mờ với Java trên OSX và thêm JLabel vào đó.Tô lại trên khung/bảng/thành phần mờ.

JLabel này thay đổi văn bản của nó mỗi giây ....

alt text

Tuy nhiên thành phần không sơn lại tốt.

Làm cách nào để giải quyết vấn đề này?

Tôi đã tìm thấy thesearticles, nhưng tôi không thể tìm ra cách giải quyết.

Nếu có thể, hãy dán mã sửa chữa nguồn, đây là của tôi:

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

Thử đặt lại nền trong mã bộ hẹn giờ quá hoặc gọi repaint trên toàn bộ bảng. Tôi điều nền chỉ không biết rằng nó cần phải được sơn lại. – jjnguy

+0

Nếu điều đó sửa chữa nó, tôi sẽ làm cho nó một câu trả lời, nhưng nó chỉ là một đoán ngay bây giờ. – jjnguy

+3

+1 để bao gồm biểu tượng SO. :-) – trashgod

Trả lời

14

Tôi đã có một số may mắn mở rộng JLabel và triển khai Icon để có được thành phần mờ hoạt động theo cách tôi muốn. Bạn có thể xem kết quả của các kết hợp quy tắc khác nhau trong số AlphaCompositeDemo này. Ví dụ dưới đây là 100% màu trắng trên đỉnh 50% màu đen.

Phụ lục: Lưu ý cách ví dụ này kết hợp văn bản mờ trên nền màn hình tắt rõ ràng trên nền khung mờ.

Phụ lục: Đây là cách để tạo whole frame translucent. Thật không may, nó cũng làm mờ nội dung.

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 để thêm ảnh chụp màn hình. Trông đầy hứa hẹn. Sự khác biệt duy nhất là, các văn bản không nên mờ, nhưng đục (như ảnh chụp màn hình này trong cửa sổ) nhưng cho tình trạng hiện tại của mã của tôi, tôi đoán điều này nên được workaround cho OSX. Tôi sẽ thử lại vào ngày mai khi tôi có máy Mac trong tay một lần nữa. Cảm ơn bạn. – OscarRyz

+0

Ồ, bạn không sử dụng JLabel nhưng vẽ trực tiếp trên bảng điều khiển ... mmhhhh Tôi phải thử điều đó. – OscarRyz

+0

Có, tại một số điểm bạn phải làm một hỗn hợp với nền của khung. Tôi sẽ cập nhật để hiển thị cách làm văn bản mờ. – trashgod

4

Vấn đề cũng có thể phải làm với thực tế rằng bạn đang thiết lập văn bản của JLabel s từ một chủ đề đó không phải là Event Dispatch Thread.

Có hai cách để giải quyết vấn đề này. Nếu không kiểm tra vấn đề của bạn, tôi sẽ giải quyết nó bằng cách sử dụng lớp javax.swing.Timer, thay vì lớp java.util.Timer. javax.swing.Timer sẽ đảm bảo rằng các sự kiện được kích hoạt trên luồng công văn.

Vì vậy, (mã chưa được kiểm tra):

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

Một cách khác để giải quyết nó là để tiếp tục sử dụng java.util.Timer nhưng để chắc chắn rằng bạn sử dụng EventQueue.invokeLater(Runnable) để đảm bảo rằng bản cập nhật cho nhãn diễn ra trên EDT.

+0

Trong trường hợp nó không rõ ràng, nếu bạn làm công cụ liên quan đến Swing TẮT EDT, sau đó bạn nhận được hiện vật như bạn đang trải qua - ví dụ như các sự kiện vẽ, có thể không hoạt động. jjnguy: việc xác nhận lại phải được kích hoạt tự động bằng phương thức setText() của JLabel; lý do một sự kiện repaint() có thể hoạt động ở đây là vì nó sẽ được lên lịch trên EDT để thực hiện sau này. Tốt hơn là hãy đảm bảo cuộc gọi setText() ban đầu đã được thực hiện trên EDT ngay từ đầu. –

+0

tôi đã cố gắng chuyển đổi các TimerTask này: timer.schedule (mới TimerTask() { int i = 0; public void run() { SwingUtilities.invokeLater (new Runnable() { public void run() { label.setText ("Hola" + i ++); } }); } }, 0, 1000); Và nó không hoạt động. Sun Bug: http://bugs.sun.com/view_bug.do?bug_id=4297006 nói rằng bạn có thể phải ghi đè lên paintComponent() vì độ mờ và mờ không tương tác tốt. – Kylar

+0

Yeap, tôi đã thử thực sự với 'SwingUtilities.invokeLater' có cùng tác dụng (gửi tin nhắn trong EDT) với kết quả chính xác như nhau. Tôi xóa nó trước khi đăng để làm cho mã ngắn gọn. – OscarRyz

2

Tôi không biết nếu vấn đề được giải quyết, nhưng tôi giải quyết nó trong ứng dụng của tôi với một "Frame.repaint();"

Vì vậy, mỗi giây Frame của tôi sẽ được sơn lại và JLabel của tôi sẽ được cập nhật theo thời gian thực tế.

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

Bạn chỉ nên tránh câu trả lời bằng mã. – croxy

Các vấn đề liên quan