动画透明背景的Linux的JFrame
我想创建一个帧(或JFrame的)一个完全透明的背景,并将它显示一个透明的动画。我设法得到它在Windows 7 X64的工作,但在同一code不上我的Linux(Lubuntu 15.04的x64)上运行。
I want to create a fully transparent background for a Frame (or JFrame) and have it show a transparent animation. I managed to get it working in Windows 7 x64 but the same code does not run on my Linux (Lubuntu x64 15.04).
在code以下显示了我想要实现 - 只需复制和放大器;粘贴。我只是想小矩形在屏幕上移动不留痕迹。
The code below shows what I'm trying to achieve--just copy & paste it. I just want the little rectangle to move across the screen without leaving a trail.
static int a = 0;
public static void main(String[] args) {
JFrame f = new JFrame();
f.setUndecorated(true);
f.setBackground(new Color(0, 0, 0, 0));
f.setVisible(true);
f.setSize(512, 512);
f.add(new JPanel() {
@Override
public void paintComponent(Graphics gr) {
Graphics2D g = (Graphics2D)gr;
g.setBackground(new Color(0, 0, 0, 0));
g.clearRect(0, 0, 512, 512);
g.drawRect(a, a++, 2, 2);
}
});
while(true) {
try {
Thread.sleep(30);
} catch(InterruptedException e) {
e.printStackTrace();
}
f.repaint();
}
}
我想什么来实现(如在Windows中所示)和我所得到的与Lubuntu 15.04:
What I want to achieve (as shown in Windows) and what I get with Lubuntu 15.04:
        
我只是想看看小方举动,就像在Windows 7上显示什么的 - 我不希望看到一个线索
I just want to see the little square move just like what's shown on Windows 7--I don't want to see a trail.
请不要给我甲骨文的透明度和窗口文档的链接 - 从来就超过了所有三次
Please don't give me the link of Oracle's transparency and window documentation--I've gone over it all thrice.
我已经试过:
- 的Graphics2D的'那么copyArea()透明空间。 (这曾经工作,据我所知,但不再做)
- 玻璃面板
- 的AlphaComposite
- setPaint()
请请你只测试出你的想法/ code第一。很多的这应该工作的东西,我已经尝试过,不似乎...所有帮助是极大的AP preciated。
Please please just test out your thoughts/code first. A lot of the "this should work" stuff I have already tried and does not seem to... All help is greatly appreciated.
有关参考,这里有一个最小的完整的例子,适合跨平台测试。需要注意的是
For reference, here's a minimal complete example, suitable for cross-platform testing. Note that
-
在某些平台上,例如Ubuntu的,一个的完全的透明背景不被视为不透明;一个小的,非零的字母的值是一个典型的解决方法。
On some platforms, e.g. Ubuntu, a completely transparent background is not seen as opaque; a small, non-zero alpha value is a typical work-around.
Swing GUI的对象应当建立和操纵的只有的上的事件调度线程。
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
使用 java.swing。定时器
,运行事件调度线程上,踱步动画。
Use java.swing.Timer
, which runs on the event dispatch thread, to pace the animation.
不要使用集preferredSize()
当你真正的意思是覆盖的 的get preferredSize()
。
Don't use setPreferredSize()
when you really mean to override getPreferredSize()
.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
/**
* @see http://stackoverflow.com/a/31328464/230513
*/
public class TransparentAnimation {
private static final Color tranparentBlack = new Color(0, 0, 0, 1);
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(tranparentBlack);
f.add(new JPanel() {
int x, y;
Timer t = new Timer(10, (ActionEvent e) -> {
x = (x + 1) % getWidth();
y = (y + 1) % getHeight();
repaint();
});
{
setBackground(tranparentBlack);
t.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g.fillOval(x, y, 16, 16);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
});
f.add(new JLabel(System.getProperty("os.name") + "; v"
+ System.getProperty("os.version")), BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new TransparentAnimation()::display);
}
}