Java透明度渲染错误

我目前正在开发一个自助服务终端风格的Java程序来显示天气,时间,预测等。这是一个程序应该是什么样子的镜头(在更新时间之前拍摄的截图)

图像显示图形错误之前所需的输出

各个部分创建为JPanels,并重写了paintComponent()方法。 它们绘制渐变标题和半透明背景。 但是,当我更改其中一个面板的内容时,之前的内容会被遗忘,而不是被删除。 一个例子如下所示:

正如你所看到的,当时间从11:51变为11:52时,数字重叠,背景变得更亮(因为半透明背景被重新绘制)

图形错误

显示图形错误的图像

我该怎么做才能防止这种重叠? 最终,当单个面板更新其内容时,我宁愿不必重绘整个屏幕。 我宁愿只重绘那个特定的部分。 重新绘制背景,然后是其中的所有组件将很容易。

更新

几个答案涉及清除要绘制的区域。 无论我使用g.clear()还是AlphaComposite.CLEAR它都会删除背景图片。 这可以在下图中看到。 也许如果我可以在清除区域之前复制背景,我可以重新绘制背景的那一部分,然后适当地对其他图像进行分层。 思考?

在此处输入图像描述

更新2

提交了一个答案,其中显示了在透明面板和背景上放置的计时器的完整工作示例。 这非常有用,但是,我不是手动绘制我的子组件。 时间,天气图标和温度都是JLabel布局在半透明面板上。 我宁愿不必手动绘制单个组件。

一个类似的问题

http://img641.imageshack.us/img641/8873/translucentfail.png之前的图片

在这里解决

http://i46.tinypic.com/6gj1gk.png之后的图片

另请注意,“Swing程序应覆盖paintComponent()而不是覆盖paint() 。” – 在AWT和Swing中绘制:绘制方法

在进行绘画之前,请进行g.clearRect(0,0,w,h)调用。 这将删除指定区域中的所有内容,并且您不会在上一帧的顶部绘制。

您可能希望应用一些双缓冲技术,因为屏幕会因清晰而略微闪烁。

我很快把它放在一起这没什么特别的……

在此处输入图像描述

整个项目由JFrame,BackgroundImagePane和ClockPane组成

ClockPane看起来像这样(因为你可以重新创建其余部分;))

 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.RoundRectangle2D; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.Timer; public class ClockPane extends javax.swing.JPanel { private Timer tick; protected static final SimpleDateFormat SDF = new SimpleDateFormat("HH:mm.ss"); public ClockPane() { setOpaque(false); tick = new Timer(500, new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { repaint(); } }); tick.setCoalesce(true); tick.setRepeats(true); setPreferredSize(new Dimension(100, 100)); setMinimumSize(new Dimension(100, 100)); } @Override public void addNotify() { super.addNotify(); tick.start(); } @Override public void removeNotify() { tick.stop(); super.removeNotify(); } @Override protected void paintComponent(Graphics grphcs) { super.paintComponent(grphcs); Graphics2D g2d = (Graphics2D) grphcs; int width = getWidth() - 1; int height = getHeight() - 1; Color background = new Color(192, 192, 192, 128); Color border = new Color(128, 128, 128); RoundRectangle2D backing = new RoundRectangle2D.Float(0, 0, width, height, 20, 20); g2d.setPaint(background); g2d.fill(backing); g2d.setPaint(border); g2d.draw(backing); String text = SDF.format(new Date()); FontMetrics fm = g2d.getFontMetrics(); g2d.setPaint(Color.BLACK); int x = (width - fm.stringWidth(text)) / 2; int y = ((height - fm.getHeight()) / 2) + fm.getAscent(); g2d.drawString(text, x, y); } } 

有了这个,时钟每半秒左右更新一次,我对重绘没有任何问题

我能想到的唯一重要的是setOpaque(false);

更新

除了标签和面板之外,此示例完全没有任何内容(背景窗格是自定义绘制作业,日期标签也绘制了背景,但除此之外)

正常组件

现在,我把我一起砍了,所以它不如你的好,但是又一次,我没有得到报酬;)

 import core.ui.UIUtilities; import core.ui.WindowUtilities; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.Timer; import javax.swing.UIManager; public class MainFrame extends javax.swing.JFrame { /** * Creates new form MainFrame */ public MainFrame() { setUndecorated(true); WindowUtilities.setOpaque(this, false); initComponents(); Timer timer = new Timer(500, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { lblTime.setText(new SimpleDateFormat("hh:MM:ss").format(new Date())); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); DateLabel label = new DateLabel(); label.init(); NewBackgroundPane backgroundPane = new NewBackgroundPane(); backgroundPane.setLayout(new BorderLayout()); backgroundPane.add(label, BorderLayout.NORTH); backgroundPane.add(pnlMain); add(backgroundPane, BorderLayout.CENTER); pack(); setLocation(UIUtilities.centerOfDefaultScreen(this)); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") //  private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; pnlMain = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel(); lblTime = new javax.swing.JLabel(); lblExtTime = new javax.swing.JLabel(); jPanel3 = new javax.swing.JPanel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); jLabel5 = new javax.swing.JLabel(); jLabel6 = new javax.swing.JLabel(); jPanel4 = new javax.swing.JPanel(); jPanel5 = new javax.swing.JPanel(); jLabel11 = new javax.swing.JLabel(); jLabel12 = new javax.swing.JLabel(); jLabel13 = new javax.swing.JLabel(); jLabel14 = new javax.swing.JLabel(); jPanel6 = new javax.swing.JPanel(); jLabel15 = new javax.swing.JLabel(); jLabel16 = new javax.swing.JLabel(); jLabel17 = new javax.swing.JLabel(); jLabel18 = new javax.swing.JLabel(); jPanel7 = new javax.swing.JPanel(); jLabel19 = new javax.swing.JLabel(); jLabel20 = new javax.swing.JLabel(); jLabel21 = new javax.swing.JLabel(); jLabel22 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); pnlMain.setOpaque(false); pnlMain.setLayout(new java.awt.GridBagLayout()); jPanel2.setOpaque(false); jPanel2.setLayout(new java.awt.GridBagLayout()); lblTime.setFont(lblTime.getFont().deriveFont(lblTime.getFont().getStyle() | java.awt.Font.BOLD, lblTime.getFont().getSize()+18)); lblTime.setForeground(new java.awt.Color(255, 255, 255)); lblTime.setText("jLabel1"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; jPanel2.add(lblTime, gridBagConstraints); lblExtTime.setFont(lblExtTime.getFont().deriveFont(lblExtTime.getFont().getSize()+6f)); lblExtTime.setForeground(new java.awt.Color(255, 255, 255)); lblExtTime.setText("AM EDT"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel2.add(lblExtTime, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2); pnlMain.add(jPanel2, gridBagConstraints); jPanel3.setOpaque(false); jPanel3.setLayout(new java.awt.GridBagLayout()); jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/transparentUpdate/Overcast.png"))); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridheight = 2; jPanel3.add(jLabel3, gridBagConstraints); jLabel4.setFont(jLabel4.getFont().deriveFont(jLabel4.getFont().getSize()+6f)); jLabel4.setForeground(new java.awt.Color(255, 255, 255)); jLabel4.setText("Currenctly
Overast"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START; jPanel3.add(jLabel4, gridBagConstraints); jLabel5.setFont(jLabel5.getFont().deriveFont(jLabel5.getFont().getSize()+12f)); jLabel5.setForeground(new java.awt.Color(255, 255, 255)); jLabel5.setText("69"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.LAST_LINE_START; jPanel3.add(jLabel5, gridBagConstraints); jLabel6.setForeground(new java.awt.Color(255, 255, 255)); jLabel6.setText("/65"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.LAST_LINE_START; jPanel3.add(jLabel6, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2); pnlMain.add(jPanel3, gridBagConstraints); jPanel4.setOpaque(false); jPanel4.setLayout(new java.awt.GridBagLayout()); jPanel5.setOpaque(false); jPanel5.setLayout(new java.awt.GridBagLayout()); jLabel11.setFont(jLabel11.getFont().deriveFont(jLabel11.getFont().getSize()+4f)); jLabel11.setForeground(new java.awt.Color(255, 255, 255)); jLabel11.setText("Today"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 2; jPanel5.add(jLabel11, gridBagConstraints); jLabel12.setForeground(new java.awt.Color(255, 255, 255)); jLabel12.setIcon(new javax.swing.ImageIcon(getClass().getResource("/transparentUpdate/SmallOvercast.png"))); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridheight = 2; jPanel5.add(jLabel12, gridBagConstraints); jLabel13.setFont(jLabel13.getFont().deriveFont(jLabel13.getFont().getSize()+4f)); jLabel13.setForeground(new java.awt.Color(255, 255, 255)); jLabel13.setText("83"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel5.add(jLabel13, gridBagConstraints); jLabel14.setForeground(new java.awt.Color(255, 255, 255)); jLabel14.setText("65"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel5.add(jLabel14, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4); jPanel4.add(jPanel5, gridBagConstraints); jPanel6.setOpaque(false); jPanel6.setLayout(new java.awt.GridBagLayout()); jLabel15.setFont(jLabel15.getFont().deriveFont(jLabel15.getFont().getSize()+4f)); jLabel15.setForeground(new java.awt.Color(255, 255, 255)); jLabel15.setText("Sunday"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 2; jPanel6.add(jLabel15, gridBagConstraints); jLabel16.setForeground(new java.awt.Color(255, 255, 255)); jLabel16.setIcon(new javax.swing.ImageIcon(getClass().getResource("/transparentUpdate/Sunny.png"))); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridheight = 2; jPanel6.add(jLabel16, gridBagConstraints); jLabel17.setFont(jLabel17.getFont().deriveFont(jLabel17.getFont().getSize()+4f)); jLabel17.setForeground(new java.awt.Color(255, 255, 255)); jLabel17.setText("82"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel6.add(jLabel17, gridBagConstraints); jLabel18.setForeground(new java.awt.Color(255, 255, 255)); jLabel18.setText("64"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel6.add(jLabel18, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4); jPanel4.add(jPanel6, gridBagConstraints); jPanel7.setOpaque(false); jPanel7.setLayout(new java.awt.GridBagLayout()); jLabel19.setFont(jLabel19.getFont().deriveFont(jLabel19.getFont().getSize()+4f)); jLabel19.setForeground(new java.awt.Color(255, 255, 255)); jLabel19.setText("Monday"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 2; jPanel7.add(jLabel19, gridBagConstraints); jLabel20.setForeground(new java.awt.Color(255, 255, 255)); jLabel20.setIcon(new javax.swing.ImageIcon(getClass().getResource("/transparentUpdate/Cloudy.png"))); // NOI18N gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridheight = 2; jPanel7.add(jLabel20, gridBagConstraints); jLabel21.setFont(jLabel21.getFont().deriveFont(jLabel21.getFont().getSize()+4f)); jLabel21.setForeground(new java.awt.Color(255, 255, 255)); jLabel21.setText("83"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel7.add(jLabel21, gridBagConstraints); jLabel22.setForeground(new java.awt.Color(255, 255, 255)); jLabel22.setText("84"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; jPanel7.add(jLabel22, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.PAGE_START; gridBagConstraints.insets = new java.awt.Insets(2, 4, 2, 4); jPanel4.add(jPanel7, gridBagConstraints); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2); pnlMain.add(jPanel4, gridBagConstraints); getContentPane().add(pnlMain, java.awt.BorderLayout.CENTER); pack(); }//
/** * @param args the command line arguments */ public static void main(String args[]) { /* * Set the Nimbus look and feel */ // /* * If Nimbus (introduced in Java SE 6) is not available, stay with the * default look and feel. For details see * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } // /* * Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MainFrame().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JLabel jLabel11; private javax.swing.JLabel jLabel12; private javax.swing.JLabel jLabel13; private javax.swing.JLabel jLabel14; private javax.swing.JLabel jLabel15; private javax.swing.JLabel jLabel16; private javax.swing.JLabel jLabel17; private javax.swing.JLabel jLabel18; private javax.swing.JLabel jLabel19; private javax.swing.JLabel jLabel20; private javax.swing.JLabel jLabel21; private javax.swing.JLabel jLabel22; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel3; private javax.swing.JPanel jPanel4; private javax.swing.JPanel jPanel5; private javax.swing.JPanel jPanel6; private javax.swing.JPanel jPanel7; private javax.swing.JLabel lblExtTime; private javax.swing.JLabel lblTime; private javax.swing.JPanel pnlMain; // End of variables declaration }

只是为了让生活变得更好,背景窗格

 import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; public class NewBackgroundPane extends javax.swing.JPanel { /** * Creates new form NewBackgroundPane */ public NewBackgroundPane() { initComponents(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); int width = getWidth() - 1; int height = getHeight() - 1; g2d.setColor(Color.LIGHT_GRAY); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)); g2d.fillRoundRect(0, 0, width, height, 20, 20); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") //  private void initComponents() { setOpaque(false); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 400, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 300, Short.MAX_VALUE) ); }//  // Variables declaration - do not modify // End of variables declaration } 

如果你仍然无法让它工作,我能想到的唯一其他问题可能与全屏,独家模式有关,我没有测试过:P