gpt4 book ai didi

java - JLabel 文本在透明背景上被覆盖

转载 作者:行者123 更新时间:2023-12-03 00:10:58 26 4
gpt4 key购买 nike

我是 java 的新手,我正在尝试创建一个像桌面小部件一样的应用程序,我已将 JPanel 设为透明。我在其顶部有两个 JLabel,一个用于保存图像,另一个用于显示时间。我有一个计时器来更新 JLabel 中显示的时间。但是,如果 jlabel 后面有一个透明的 JPanel,则文本会被覆盖而不是替换。在 Google 和 stackoverflow 上查找后,我尝试了许多方法来重写 JLabel 的 PaintComponent 方法。但这并没有影响任何事情。后来我手动调用了定时器内部的paintComponent方法,结果成功了。但我觉得这只是一个解决方法。我需要知道为什么 PaintComponent 没有被调用以及它通常何时被调用。

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.SwingConstants;
import javax.swing.text.SimpleAttributeSet;

import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class WindowSample {

private JFrame frame;
MyLabel panel1;

// JLabel panel1;

/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowSample window = new WindowSample();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the application.
*/
public WindowSample() {
initialize();
}

/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(dim);
frame.setBounds(0, 0, 500, 500);
frame.setBackground(new Color(0, 255, 0, 0));
frame.setUndecorated(true);
frame.setContentPane(new ContentPane());
frame.getContentPane().setBackground(Color.WHITE);
frame.getContentPane().setLayout(null);

// ImagePanel panel = new ImagePanel();
JLabel panel = new JLabel(
scale(new ImageIcon("Science Drops.png").getImage()));
panel.setBounds(0, 0, 200, 200);

panel1 = new MyLabel();
// panel1 = new JLabel();

panel1.setHorizontalAlignment(SwingConstants.CENTER);
panel1.setAlignmentX(SwingConstants.CENTER);
panel1.setFont(new Font("Calibiri",Font.BOLD,16));
panel1.setBounds(0, 205, 200, 50);
Timer n = new Timer();
panel1.setBackground(Color.white);

n.scheduleAtFixedRate(new TimerTask() {

@Override
public void run() {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
// this manual call to paintComponent did the trick. If i remove this line the text gets overwritten over itself for every second.
panel1.paintComponents(panel1.getGraphics());
panel1.setText(df.format(new Date()));

}
}, 1000, 1000);
frame.getContentPane().add(panel1);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

@SuppressWarnings("serial")
public class MyLabel extends JLabel {
MyLabel() {
setOpaque(false);
}

@Override
public void paintComponents(Graphics arg0) {
Graphics2D g2d = (Graphics2D) arg0.create();
g2d.clearRect(0, 0, getWidth(), getHeight());
g2d.dispose();
super.paintComponents(arg0);
}
}

public class ContentPane extends JPanel {

public ContentPane() {

setOpaque(false);

}

@Override
protected void paintComponent(Graphics g) {

Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f));

g2d.setColor(getBackground());
g2d.fill(getBounds());

g2d.dispose();
super.paintComponent(g);

}

}

public ImageIcon scale(Image src) {
int w = 200;
int h = 200;
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage dst = new BufferedImage(w, h, type);
Graphics2D g2 = dst.createGraphics();
g2.drawImage(src, 0, 0, w, h, frame);
g2.dispose();
return new ImageIcon(dst);
}
}

最佳答案

阅读Backgrounds With Transparency了解有关透明度如何发挥作用以及一些可能的解决方案的信息。

此外,您的代码还有一些其他注释:

  1. 不要使用空布局。 Swing 被设计为与布局管理器一起使用,原因有很多,在此列出。
  2. 自定义绘制是通过重写paintComponent()(无“s”)来完成的。但是,就您而言,如果您遵循我上面提供的链接中的建议,我认为没有任何理由进行自定义绘画。我也不认为您需要在面板中进行自定义绘画,但我不完全理解您想要做什么。

关于java - JLabel 文本在透明背景上被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18909203/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com