java中的setOpaque()

java中的setOpaque(),java,swing,look-and-feel,nimbus,Java,Swing,Look And Feel,Nimbus,有人能解释为什么Nimbius对set不透明()的处理不同于其他java LaF吗。它破坏了我的代码,因为通常是透明的组件不再是透明的 编辑:这个问题似乎只涉及JTextAreas(这是我所需要的)或类似的组件 编辑:这是实际应用程序的屏幕。当应用垃圾神的解决方案时,背景仍然无法显示出来 编辑:我尝试了垃圾神的建议来覆盖油漆()。我为此辛辛苦苦地工作了好几个小时,却无法使它发挥作用。我可以让背景显示出来,但是JinternalFrame无法移动、调整大小和选择文本。调用super.paint(

有人能解释为什么Nimbius对set不透明()的处理不同于其他java LaF吗。它破坏了我的代码,因为通常是透明的组件不再是透明的

编辑:这个问题似乎只涉及JTextAreas(这是我所需要的)或类似的组件

编辑:这是实际应用程序的屏幕。当应用垃圾神的解决方案时,背景仍然无法显示出来

编辑:
我尝试了垃圾神的建议来覆盖油漆()。我为此辛辛苦苦地工作了好几个小时,却无法使它发挥作用。我可以让背景显示出来,但是JinternalFrame无法移动、调整大小和选择文本。调用super.paint(g)未能解决该解决方案。有没有一个简单的方法可以做到这一点,我可能会错过?
我对此采取了新的方法。JInternalFrame内有一个JLayeredPane。
第0层-JLabel
第1层-JTextArea

移动或调整JInternalFrame的大小时:

  • 使自己隐形
  • 对其所在容器中的位置进行屏幕截图
  • 用拍摄的图像绘制JLabel
  • 使自己再次可见
  • 因为我根本无法让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();
                }
            });
        }
    }