如何在禁用突出显示的其他组件中安排透明的 JTextPane
How to arrange a transparent JTextPane in other components with disabled highlighting
请问有人可以提示我如何显示透明的 JTextPane
,它是 JScrollPane
和 JPanel
等其他组件的子组件。我使用了 AlphaContainer
可用 here 来提高透明度。
这是有效的:
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
中,则会再次启用突出显示(和越野车):
chatTextPane = new JTextPane();
chatTextPane.setEditable(false);
chatTextPane.setHighlighter(null);
chatTextPane.setBackground(new Color(255,255,255,100));
JScrollPane scrollPane = new JScrollPane(chatTextPane);
scrollPane.setOpaque(false);
AlphaContainer ac = new AlphaContainer(scrollPane);
JPanel chatPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
chatPanel.setOpaque(false);
chatPanel.add(ac);
然后看起来像这样:
最后,我最初想将它添加到另一个面板中,在 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 组件具有 parent/child 关系。在您的情况下,它看起来像:
- JFrame
- 内容面板(带有自定义背景颜色)
- 聊天面板
- JScrollPane
- J视口
- JTextPane
Swing 在子组件之前绘制父组件。因此,您希望首先绘制内容窗格(不透明),然后绘制“ChatPanel”(半透明),然后所有其他子组件不透明。
所以有一些变化:
- 需要在添加到内容窗格的组件上使用
AlphaContainer
。
您可以使用:
//frame.add(chatPanel);
frame.add( new AlphaContainer(chatPanel) );
注意:AlphaContainer
将使添加到其中的组件不透明,因此您无需显式使用 setOpaque( false );
您需要使 JTextPane 不透明(因为没有孤独者添加到 AlphaContainer)。
您还需要使 JViewport
不透明。
这是通过使用完成的:
scrollPane.getViewport().setOpaque( false );
也不要使用:
chatTextPane.setPreferredSize(new Dimension(300, 300));
只有当组件的首选大小大于滚动窗格的大小时,滚动条才会出现。如果您对首选大小进行硬编码,则不会出现滚动条,因为首选大小不会随着您向文本区域添加文本而改变。
设置滚动窗格的首选大小。
请问有人可以提示我如何显示透明的 JTextPane
,它是 JScrollPane
和 JPanel
等其他组件的子组件。我使用了 AlphaContainer
可用 here 来提高透明度。
这是有效的:
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
中,则会再次启用突出显示(和越野车):
chatTextPane = new JTextPane();
chatTextPane.setEditable(false);
chatTextPane.setHighlighter(null);
chatTextPane.setBackground(new Color(255,255,255,100));
JScrollPane scrollPane = new JScrollPane(chatTextPane);
scrollPane.setOpaque(false);
AlphaContainer ac = new AlphaContainer(scrollPane);
JPanel chatPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
chatPanel.setOpaque(false);
chatPanel.add(ac);
然后看起来像这样:
最后,我最初想将它添加到另一个面板中,在 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 组件具有 parent/child 关系。在您的情况下,它看起来像:
- JFrame
- 内容面板(带有自定义背景颜色)
- 聊天面板
- JScrollPane
- J视口
- JTextPane
- J视口
- JScrollPane
- 聊天面板
- 内容面板(带有自定义背景颜色)
Swing 在子组件之前绘制父组件。因此,您希望首先绘制内容窗格(不透明),然后绘制“ChatPanel”(半透明),然后所有其他子组件不透明。
所以有一些变化:
- 需要在添加到内容窗格的组件上使用
AlphaContainer
。
您可以使用:
//frame.add(chatPanel);
frame.add( new AlphaContainer(chatPanel) );
注意:AlphaContainer
将使添加到其中的组件不透明,因此您无需显式使用 setOpaque( false );
您需要使 JTextPane 不透明(因为没有孤独者添加到 AlphaContainer)。
您还需要使
JViewport
不透明。
这是通过使用完成的:
scrollPane.getViewport().setOpaque( false );
也不要使用:
chatTextPane.setPreferredSize(new Dimension(300, 300));
只有当组件的首选大小大于滚动窗格的大小时,滚动条才会出现。如果您对首选大小进行硬编码,则不会出现滚动条,因为首选大小不会随着您向文本区域添加文本而改变。
设置滚动窗格的首选大小。