英文:
Text Overlaps when JTextArea background is set to transparent
问题
我试图创建一个透明的JTextArea,但更新的文本与之前的文本重叠。
我尝试使用滚动窗格(scrollpane)、边框布局(borderlayout)以及TextArea的setOpaque(false)方法,但它们都没有起作用。
![enter image description here][2]
**透明背景 ->**
![enter image description here][1]
以下是代码部分
``` Java
public class PanelTest {
public static void main(String[] args) {
PanelTest test = new PanelTest();
test.createUI();
}
public void createUI() {
JFrame frame = new JFrame("Panel Test");
frame.setUndecorated(true);
frame.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
JTextArea jTextArea = new JTextArea("");
jTextArea.setEditable(false);
jTextArea.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
jTextArea.setRows(12);
jTextArea.setColumns(7);
frame.add(jTextArea);
frame.setResizable(true);
frame.pack();
frame.setVisible(true);
Thread t = new Thread() {
public void run() {
while (true) {
String s = execute("cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq");
System.out.println(s.length());
jTextArea.setText(s);
try {
this.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
}
<details>
<summary>英文:</summary>
I'm trying to create a transparent JTextArea but the updated text overlaps with the previous one.
I tried using scrollpane, borderlayout and setOpaque(false) method of TextArea but none of them worked.
![enter image description here][2]
**Transparent Background - >**
![enter image description here][1]
Here is the code
public class PanelTest {
public static void main(String[] args) {
PanelTest test = new PanelTest();
test.createUI();
}
public void createUI() {
JFrame frame = new JFrame("Panel Test");
frame.setUndecorated(true);
frame.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
JTextArea jTextArea = new JTextArea("");
jTextArea.setEditable(false);
jTextArea.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
jTextArea.setRows(12);
jTextArea.setColumns(7);
frame.add(jTextArea);
frame.setResizable(true);
frame.pack();
frame.setVisible(true);
Thread t = new Thread(){
public void run(){
while (true) {
String s = execute("cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq");
System.out.println(s.length());
jTextArea.setText(s);
try {
this.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
}
[1]: https://i.stack.imgur.com/7D2LL.jpg
[2]: https://i.stack.imgur.com/gi2zX.jpg
</details>
# 答案1
**得分**: 1
不要使用 `new Color(1.0f, 1.0f, 1.0f, 1.0f)` 来使 `JTextArea` 透明。改为使用 `setOpaque(false)`。
此外,在事件分派线程之外不要更新组件。当你想要运行“繁重/长时间”任务时,应使用 `SwingWorker`,并使用 `publish` 方法将更新发布到 UI 线程(称为事件分派线程)。我建议你阅读 [Swing 中的并发性][1],以了解在 Swing 环境中涉及线程时应该如何工作。
以下是一个完整的示例,读取执行 `java -version` 时终端的输出。注意 `process.getErrorStream`。`java -version` 命令写入错误流。你可能需要进行更改。
```java
public class PanelTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
PanelTest test = new PanelTest();
test.createUI();
});
}
public void createUI() {
JFrame frame = new JFrame("Panel Test");
frame.setLayout(new BorderLayout());
frame.setUndecorated(true);
frame.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
JTextArea jTextArea = new JTextArea("");
jTextArea.setEditable(false);
jTextArea.setOpaque(false);
jTextArea.setRows(12);
jTextArea.setColumns(7);
frame.add(jTextArea);
frame.setResizable(true);
frame.pack();
frame.setVisible(true);
SwingWorker<Void, String> terminalReader = new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() throws Exception {
while (true) {
String s = executeTerminalCommand("java -version");
publish(s);
Thread.sleep(2000);
}
}
@Override
protected void process(List<String> chunks) {
if (!chunks.isEmpty()) {
String text = chunks.get(0);
jTextArea.setText("");
jTextArea.setText(text);
jTextArea.repaint();
}
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
};
terminalReader.execute();
}
private static String executeTerminalCommand(String command) throws IOException {
Process process = Runtime.getRuntime().exec(command);
return readInputStreamAsString(process.getErrorStream());
}
public static String readInputStreamAsString(InputStream in) throws IOException {
try (BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream buf = new ByteArrayOutputStream();) {
int result = bis.read();
while (result != -1) {
byte b = (byte) result;
buf.write(b);
result = bis.read();
}
return buf.toString();
}
}
}
英文:
Don't use a new Color(1.0f, 1.0f, 1.0f, 1.0f)
in order to make the JTextArea
transparent. Use setOpaque(false)
instead.
Also, do not make updates to components outside of event dispatch thread. When you want to run a "heavy/long" task you should use a SwingWorker
and publish updates to the UI thread (called Event dispatch thread) by using publish
method. I recommend you to read Concurrency in Swing in order to understand how things should work in a Swing environment when it comes to threading.
A full example that reads terminal's output when executing java -version
. Notice the process.getErrorStream
. java -version
command writes to error stream. You might want to change that.
public class PanelTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
PanelTest test = new PanelTest();
test.createUI();
});
}
public void createUI() {
JFrame frame = new JFrame("Panel Test");
frame.setLayout(new BorderLayout());
frame.setUndecorated(true);
frame.setBackground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
JTextArea jTextArea = new JTextArea("");
jTextArea.setEditable(false);
jTextArea.setOpaque(false);
jTextArea.setRows(12);
jTextArea.setColumns(7);
frame.add(jTextArea);
frame.setResizable(true);
frame.pack();
frame.setVisible(true);
SwingWorker<Void, String> terminalReader = new SwingWorker<Void, String>() {
@Override
protected Void doInBackground() throws Exception {
while (true) {
String s = executeTerminalCommand("java -version");
publish(s);
Thread.sleep(2000);
}
}
@Override
protected void process(List<String> chunks) {
if (!chunks.isEmpty()) {
String text = chunks.get(0);
jTextArea.setText("");
jTextArea.setText(text);
jTextArea.repaint();
}
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
};
terminalReader.execute();
}
private static String executeTerminalCommand(String command) throws IOException {
Process process = Runtime.getRuntime().exec(command);
return readInputStreamAsString(process.getErrorStream());
}
public static String readInputStreamAsString(InputStream in) throws IOException {
try (BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream buf = new ByteArrayOutputStream();) {
int result = bis.read();
while (result != -1) {
byte b = (byte) result;
buf.write(b);
result = bis.read();
}
return buf.toString();
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论