java中的setOpaque()
有人能解释为什么Nimbius对set不透明()的处理不同于其他java LaF吗。它破坏了我的代码,因为通常是透明的组件不再是透明的 编辑:这个问题似乎只涉及JTextAreas(这是我所需要的)或类似的组件 编辑:这是实际应用程序的屏幕。当应用垃圾神的解决方案时,背景仍然无法显示出来 编辑:java中的setOpaque(),java,swing,look-and-feel,nimbus,Java,Swing,Look And Feel,Nimbus,有人能解释为什么Nimbius对set不透明()的处理不同于其他java LaF吗。它破坏了我的代码,因为通常是透明的组件不再是透明的 编辑:这个问题似乎只涉及JTextAreas(这是我所需要的)或类似的组件 编辑:这是实际应用程序的屏幕。当应用垃圾神的解决方案时,背景仍然无法显示出来 编辑:我尝试了垃圾神的建议来覆盖油漆()。我为此辛辛苦苦地工作了好几个小时,却无法使它发挥作用。我可以让背景显示出来,但是JinternalFrame无法移动、调整大小和选择文本。调用super.paint(
我尝试了垃圾神的建议来覆盖油漆()。我为此辛辛苦苦地工作了好几个小时,却无法使它发挥作用。我可以让背景显示出来,但是JinternalFrame无法移动、调整大小和选择文本。调用super.paint(g)未能解决该解决方案。有没有一个简单的方法可以做到这一点,我可能会错过?
我对此采取了新的方法。JInternalFrame内有一个JLayeredPane。
第0层-JLabel
第1层-JTextArea
移动或调整JInternalFrame的大小时:
package newpackage;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
/**
* Example of how to create a transparent internal frame.
* @author dvargo
*/
public class TransparentInternalFrame extends JInternalFrame {
JLayeredPane container;
/**
* Defualt constructor to set the frame up
* @param container The container for the frame
* @param opacity The opacity of the frame
*/
public TransparentInternalFrame(JLayeredPane container, int opacity) {
super("", true, true, true, true);
this.container = container;
initComponents();
setSize(200, 200);
putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
scrollPane.setBackground(new Color(0, 0, 0, opacity));
scrollPane.getViewport().setBackground(new Color(0, 0, 0, opacity));
textArea.setBackground(new Color(0, 0, 0, opacity));
setBG();
}
/**
* Builds the GUI
*/
private void initComponents() {
layeredPane = new javax.swing.JLayeredPane();
imageLabel = new javax.swing.JLabel();
scrollPane = new javax.swing.JScrollPane();
textArea = new javax.swing.JTextArea();
imageLabel.setBounds(0, 0, 360, 260);
layeredPane.add(imageLabel, javax.swing.JLayeredPane.DEFAULT_LAYER);
scrollPane.setBorder(null);
textArea.setColumns(20);
textArea.setRows(5);
textArea.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
textAreaKeyPressed(evt);
}
public void keyReleased(java.awt.event.KeyEvent evt) {
textAreaKeyReleased(evt);
}
public void keyTyped(java.awt.event.KeyEvent evt) {
textAreaKeyTyped(evt);
}
});
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentMoved(java.awt.event.ComponentEvent evt) {
frameMoved();
}
public void componentResized(java.awt.event.ComponentEvent evt) {
frameResized();
}
});
scrollPane.setViewportView(textArea);
scrollPane.setBounds(0, 0, 360, 260);
layeredPane.add(scrollPane, javax.swing.JLayeredPane.PALETTE_LAYER);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 362, javax.swing.GroupLayout.PREFERRED_SIZE));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE));
}
/**
* The text will be blurred with out this
* @param evt
*/
private void textAreaKeyTyped(java.awt.event.KeyEvent evt) {
repaintAll();
}
/**
* The text will be blurred with out this
* @param evt
*/
private void textAreaKeyPressed(java.awt.event.KeyEvent evt) {
repaintAll();
}
/**
* The text will be blurred with out this
* @param evt
*/
private void textAreaKeyReleased(java.awt.event.KeyEvent evt) {
repaintAll();
}
/**
* Capture whats behind the frame and paint it to the image label
*/
private void setBG() {
setVisible(false);
Rectangle location = new Rectangle(this.getX() + container.getX(),
this.getY() + container.getY(),
(int) this.getSize().getWidth() + 8 + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getWidth(),
(int) this.getSize().getHeight() + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getHeight() + 4);
ImageIcon newIcon = new ImageIcon(createImage((JComponent) container, location));
setVisible(true);
imageLabel.setIcon(newIcon);
repaint();
}
/**
* Only need to update the image label if the frame is moved or resized
*/
private void frameResized() {
setBG();
textArea.repaint();
}
/**
* Only need to update the image label if the frame is moved or resized
*/
private void frameMoved() {
setBG();
for(Component x : container.getComponents())
{
//see if its a jinternalframe
if(x.getClass().getName().equals(this.getClass().getName()))
{
//cast it
TransparentInternalFrame temp = (TransparentInternalFrame)x;
//make sure its not the same one as this
if(x.getBounds().equals(this.getBounds()))
{
return;
}
//if they intersect
if(x.getBounds().intersects(this.getBounds()))
{
this.setVisible(false);
temp.setBG();
this.setVisible(true);
}
}
}
textArea.repaint();
}
private void repaintAll() {
textArea.repaint();
imageLabel.repaint();
layeredPane.repaint();
scrollPane.repaint();
scrollPane.getViewport().repaint();
textArea.repaint();
repaint();
}
/**
* Create a BufferedImage for Swing components.
* All or part of the component can be captured to an image.
*
* @param component Swing component to create image from
* @param region The region of the component to be captured to an image
* @return image the image for the given region
*/
public static BufferedImage createImage(JComponent component, Rectangle region) {
// Make sure the component has a size and has been layed out.
// (necessary check for components not added to a realized frame)
if (!component.isDisplayable()) {
Dimension d = component.getSize();
if (d.width == 0 || d.height == 0) {
d = component.getPreferredSize();
component.setSize(d);
}
layoutComponent(component);
}
BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
// Paint a background for non-opaque components,
// otherwise the background will be black
if (!component.isOpaque()) {
g2d.setColor(component.getBackground());
g2d.fillRect(region.x, region.y, region.width, region.height);
}
g2d.translate(-region.x, -region.y);
component.paint(g2d);
g2d.dispose();
return image;
}
public static void layoutComponent(Component component) {
synchronized (component.getTreeLock()) {
component.doLayout();
if (component instanceof Container) {
for (Component child : ((Container) component).getComponents()) {
layoutComponent(child);
}
}
}
}
private javax.swing.JLabel imageLabel;
private javax.swing.JScrollPane scrollPane;
private javax.swing.JLayeredPane layeredPane;
private javax.swing.JTextArea textArea;
public static void main(String args[])
{
try
{
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch (Exception e)
{
e.printStackTrace();
}
JFrame container = new JFrame();
container.setSize(800, 800);
JLayeredPane layerPanel = new JLayeredPane();
layerPanel.setSize(800, 800);
container.getContentPane().add(layerPanel);
layerPanel.setVisible(true);
JPanel colorPanel = new JPanel();
colorPanel.setSize(800,800);
colorPanel.setBackground(Color.red);
layerPanel.add(colorPanel);
layerPanel.setLayer(colorPanel, JLayeredPane.DEFAULT_LAYER);
TransparentInternalFrame frameA = new TransparentInternalFrame(layerPanel,0);
frameA.setVisible(true);
layerPanel.add(frameA);
layerPanel.setLayer(frameA, 1);
frameA.setSize(282,282);
TransparentInternalFrame frameB = new TransparentInternalFrame(layerPanel, 0);
frameB.setVisible(true);
layerPanel.add(frameB);
layerPanel.add(frameB,1);
frameB.setLocation(300, 300);
frameB.setSize(282,282);
container.repaint();
container.setVisible(true);
}
}
您可能会从本文中关于的部分获得一些见解。特别是,设置不透明属性并不意味着“使组件的背景透明”。证明该问题的方法可能也会有成效 附录:简化您的示例,看起来文本区域本身可以变得透明,但颜色会影响区域的边界。您可以尝试相应地更改它们 关于代码的一些注释:
- 始终在事件分派线程上构建GUI
- 不要从另一根线上画
- 不要吞下例外
create()
的更改
增编:你可能也想看看这个房产
jif.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE);
正如前面所解释的,setOpaque并没有做你认为它会做的事情,在Nimbus中,失败是显而易见的。另一个关于alpha颜色的答案是实现您所需的正确方法。谢谢,这是非常有用的。我试图不依赖set不透明()使组件透明,而是使组件的背景具有0 alpha值。我添加了一个sscce。谢谢你的简化代码。这很有效。对于我的特殊问题,TransparentTextArea将包含在一个JInternalFrame中。我尝试将TransparentTextArea添加到JInternalFrame,将背景设置为具有0 alpha值的颜色和/或设置不透明(false),但在这种情况下,背景不会显示出来。关于修改代码以允许它与JInternalFrame一起工作,有什么建议吗?再次感谢您的帮助。@user489041:当我在
create()
中将面板添加到内部框架时,它似乎起作用了。很抱歉延迟回复。@trashgood:谢谢回复。在更新的代码中,JPanel被添加到JInternalFrame中。然后将JPanel的背景设置为与JFrame相同的颜色。然而,显示出来的不是JFrame的背景,而是JPanel。我需要让JInternalFrame完全透明,只显示文本和JFrame的背景。我试着改变JPanel的颜色,但没有效果。我仍然无法显示JInternalFrame后面的图像。我加了一张我实际申请的照片来说明这个问题。有什么想法吗?@user489041:啊,我觉得JTextArea
需要透明。要使JInternalFrame
透明,可以将InternalFrameUI
子类化,并覆盖paint()
。重新格式化代码;如果不正确,请还原。当我将JInternalFrame的背景alpha颜色设置为0时,它将不允许JFrames背景显示出来。对上述sscce代码有任何建议吗?请尝试以下代码:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JInternalFrame;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.UIManager;
public class TransparentTextArea extends JTextArea {
int alpha;
public TransparentTextArea(int alpha) {
super(4, 16);
this.alpha = alpha;
this.setBackground(new Color(0, 0, 0, alpha));
this.setFont(new Font("Serif", Font.ITALIC, 24));
this.setEditable(false);
this.setText("Twas brillig and the slithy toves,\n"
+ "Did gyre and gimble in the wabe;\n"
+ "All mimsy were the borogoves,\n"
+ "And the mome raths outgrabe.");
}
private static void create() {
JFrame f = new JFrame();
f.setLayout(new FlowLayout());
f.getContentPane().setBackground(new Color(0xffffc0));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JInternalFrame jif = new JInternalFrame();
JPanel panel = new JPanel();
panel.setBackground(new Color(0xffffc0));
panel.add(new TransparentTextArea(0));
jif.add(panel);
jif.setVisible(true);
f.add(jif);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
create();
}
});
}
}