Java 如何在禁用高亮显示的其他组件中排列透明JTextPane

Java 如何在禁用高亮显示的其他组件中排列透明JTextPane,java,swing,transparency,highlight,jtextpane,Java,Swing,Transparency,Highlight,Jtextpane,有人能告诉我如何显示透明的JTextPane,它是JScrollPane和JPanel等其他组件的子组件。我使用了一个透明的AlphaContainer 这是有效的: chatTextPane = new JTextPane(); chatTextPane.setEditable(false); chatTextPane.setHighlighter(null); chatTextPane.setBackground(new Color(255,255,255,100)); AlphaConta

有人能告诉我如何显示透明的
JTextPane
,它是
JScrollPane
JPanel
等其他组件的子组件。我使用了一个透明的
AlphaContainer

这是有效的:

chatTextPane = new JTextPane();
chatTextPane.setEditable(false);
chatTextPane.setHighlighter(null);
chatTextPane.setBackground(new Color(255,255,255,100));
AlphaContainer ac = new AlphaContainer(chatTextPane);   

JPanel chatPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
chatPanel.setOpaque(false);
chatPanel.add(ac);
看起来是这样的:

但是,如果我将它包装成非不透明的
JScrollPane
,它就不再是透明的了。如果我将
JScrollPane
放在
AlphaContainer
中,高亮显示将再次启用(并且出现错误):

看起来是这样的:

最后,我最初想将它添加到另一个面板中,在
BoxLayout
中也有
JTextField
。如果我尝试这样做,
JTextField
将显示两次:一次正确显示在底部,另一次正确显示在顶部(不可编辑)

我已经试着解决这个问题好几个小时了,我对一切都心存感激

下面是第二个示例的可运行代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MyClass {
    public static void main(String args[]) {
        new MyClass();
    }

    public MyClass() {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
                        | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setBackground(new Color(100, 0, 0, 255));

                //
                JTextPane chatTextPane = new JTextPane();
                chatTextPane.setEditable(false);
                chatTextPane.setHighlighter(null);
                chatTextPane.setPreferredSize(new Dimension(300, 300));
                chatTextPane.setBackground(new Color(255,255,255,100));
                chatTextPane.setText("testtesttesttesttesttest");
                JScrollPane scrollPane = new JScrollPane(chatTextPane);
                scrollPane.setOpaque(false);
                AlphaContainer ac = new AlphaContainer(scrollPane);

                JPanel chatPanel = new JPanel();
                chatPanel.setOpaque(false);
                chatPanel.add(ac);              
                //
                
                frame.add(chatPanel);
                frame.pack();
                frame.setVisible(true);
            }

        });
    }

    private class AlphaContainer extends JComponent {
        private JComponent component;

        public AlphaContainer(JComponent component) {
            this.component = component;
            setLayout(new BorderLayout());
            setOpaque(false);
            component.setOpaque(false);
            add(component);
        }

        /**
         * Paint the background using the background Color of the contained component
         */
        @Override
        public void paintComponent(Graphics g) {
            g.setColor(component.getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    }
}

Swing组件具有父/子关系。在您的情况下,它看起来像:

  • JFrame
    • 内容窗格(具有自定义背景色)
      • 聊天面板
        • JScrollPane
          • JViewport
            • JTextPane
Swing在子组件之前绘制父组件。因此,您希望先绘制内容窗格(不透明),然后绘制“聊天面板”(半透明),然后所有其他子组件都是不透明的

所以有几个变化:

  • 需要在添加到内容窗格的组件上使用
    AlphaContainer
  • 您可以通过以下方式执行此操作:

    //frame.add(chatPanel);
    frame.add( new AlphaContainer(chatPanel) );
    
    scrollPane.getViewport().setOpaque( false );
    
    注意:
    AlphaContainer
    将使添加到其中的组件不不透明,因此不需要显式使用setOpaque(false)

  • 您需要使JTextPane非不透明(因为AlphaContainer中没有添加loner)

  • 您还需要使
    JViewport
    不不透明

  • 这是通过使用:

    //frame.add(chatPanel);
    frame.add( new AlphaContainer(chatPanel) );
    
    scrollPane.getViewport().setOpaque( false );
    
    也不要使用:

    chatTextPane.setPreferredSize(new Dimension(300, 300));
    
    只有当组件的首选大小大于滚动窗格的大小时,滚动条才会出现。如果硬编码首选大小,则不会显示滚动条,因为在向文本区域添加文本时首选大小不会改变


    设置滚动窗格上的首选大小。

    但是,如果我将其包装到非不透明的JScrollPane中,它将不再是透明的。-文本窗格是透明的,但滚动窗格不是,并且滚动窗格的视口不是透明的。张贴你的演示问题。我已经上传了不工作示例的可运行代码。代码应该发布在这里的论坛中,这样我们就可以看到代码,而无需通过其他网站的链接。我已将代码添加到问题(1+)中。。