在半透明的JFrame上删除没有setOpaque()的JTextPane的白色背景 [英] Remove JTextPane's white background without setOpaque() over a translucent JFrame
问题描述
我有一个Java代码,在其中实现了半透明的JPanel,并使用Graphics 2D在其上绘制了图像.此图像是一个PNG,在整个JFrame中都包含一个80%不透明的白色矩形.现在,我需要添加一个JTextPane来显示数据(我将其设置为使用来自应用程序包BTW的自定义字体),但是我无法使其变得半透明:其白色背景是不透明的(即使使用textPane.setOpaque(false);
设置也是如此) ),并且使我的JFrame的透明度变得毫无用处.
因此,我正在寻找一种方法来消除这种吓到我的白色背景.
我进行了许多Google搜索,但是发现的所有内容都是设置JTextPane的不透明度的布尔值.我还发现,使用Graphics 2D可以创建自定义JTextPane并覆盖其背景,但是它没有用...我已经尝试了所有这些方法.
public class MyWindow extends JFrame {
private static class MyTextPane extends JTextPane {
public MyTextPane() {
super();
setText("Hello World");
setOpaque(false);
setBackground(new Color(0,0,0,0));
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
}
public static void main(String[] args) {
MyTextPane textPane = new MyTextPane();
JPanel panel = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
try {
Image img = ImageIO.read(new File("images/bg.png"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
} catch (IOException e) {
e.printStackTrace();
}
if (g instanceof Graphics2D) {
final int R = 240;
final int G = 240;
final int B = 240;
Paint p =
new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0),
0.0f, getHeight(), new Color(R, G, B, 0), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
};
panel.add(textPane);
setContentPane(panel);
}
(在JFrame上添加了Oracle的解释,在这里解决方案
这就是我可能会采用的这种方法...
public class OverlayTextArea {
public static void main(String[] args) {
new OverlayTextArea();
}
public OverlayTextArea() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new ImagePane());
frame.setLayout(new BorderLayout());
frame.add(new TransparentTextArea());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TransparentTextArea extends JTextArea {
public TransparentTextArea() {
setOpaque(false);
setBorder(new CompoundBorder(new EmptyBorder(10, 10, 10, 10), new LineBorder(Color.LIGHT_GRAY)));
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(new Color(255, 255, 255, 128));
Insets insets = getInsets();
int x = insets.left;
int y = insets.top;
int width = getWidth() - (insets.left + insets.right);
int height = getHeight() - (insets.top + insets.bottom);
g.fillRect(x, y, width, height);
super.paintComponent(g);
}
}
public class ImagePane extends JPanel {
private BufferedImage background;
public ImagePane() {
try {
background = ImageIO.read(new File("/path/to/background.img"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;
g.drawImage(background, x, y, this);
}
}
}
}
反馈
- 您真的应该调用
super.paintComponent
,否则可能会导致严重的麻烦,尤其是在处理透明组件时. - 不要在
paintXxx
方法内执行任何长时间运行的任务,例如加载图像.这些方法旨在快速返回,并且可以连续多次调用...
I have a Java code where I implemented a translucent JPanel with an image drawn on it with Graphics 2D. This image is a PNG that includes a white rectangle, 80% opaque, all over the JFrame. Now I need to add a JTextPane to display datas (I set it to use a custom font from the app package BTW), but I can't manage to make it translucent : its white background is opaque (even with the textPane.setOpaque(false);
setting) and makes the transparency of my JFrame a bit useless... Wich is not cool.
So I am looking for a way to remove this white background that freaks me out.
I rolled many Google searches but everything I found was a boolean to set the opacity of the JTextPane. I also found that with the Graphics 2D I could create a custom JTextPane and Override its background, but It didn't work... I HAVE already tried all of this.
public class MyWindow extends JFrame {
private static class MyTextPane extends JTextPane {
public MyTextPane() {
super();
setText("Hello World");
setOpaque(false);
setBackground(new Color(0,0,0,0));
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
}
public static void main(String[] args) {
MyTextPane textPane = new MyTextPane();
JPanel panel = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
try {
Image img = ImageIO.read(new File("images/bg.png"));
g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
} catch (IOException e) {
e.printStackTrace();
}
if (g instanceof Graphics2D) {
final int R = 240;
final int G = 240;
final int B = 240;
Paint p =
new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0),
0.0f, getHeight(), new Color(R, G, B, 0), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
};
panel.add(textPane);
setContentPane(panel);
}
(Made the JFrame translucent with the explanations of Oracle, right here HERE) Thanks!
This is how I might approach this kind of idea...
public class OverlayTextArea {
public static void main(String[] args) {
new OverlayTextArea();
}
public OverlayTextArea() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new ImagePane());
frame.setLayout(new BorderLayout());
frame.add(new TransparentTextArea());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TransparentTextArea extends JTextArea {
public TransparentTextArea() {
setOpaque(false);
setBorder(new CompoundBorder(new EmptyBorder(10, 10, 10, 10), new LineBorder(Color.LIGHT_GRAY)));
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(new Color(255, 255, 255, 128));
Insets insets = getInsets();
int x = insets.left;
int y = insets.top;
int width = getWidth() - (insets.left + insets.right);
int height = getHeight() - (insets.top + insets.bottom);
g.fillRect(x, y, width, height);
super.paintComponent(g);
}
}
public class ImagePane extends JPanel {
private BufferedImage background;
public ImagePane() {
try {
background = ImageIO.read(new File("/path/to/background.img"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;
g.drawImage(background, x, y, this);
}
}
}
}
Feedback
- You really should call
super.paintComponent
, failing to do so can lead it some serious trouble, especially when you're dealing with transparent components. - Don't perform any long running tasks within the
paintXxx
methods, like loading images. These methods are intended to return quickly and may be called multiple times within succession...
这篇关于在半透明的JFrame上删除没有setOpaque()的JTextPane的白色背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!