java jlabel在windows中工作,但在linux中不工作,在屏幕上显示旧格式,openjdk?

java jlabel在windows中工作,但在linux中不工作,在屏幕上显示旧格式,openjdk?,java,swing,ubuntu,jlabel,openjdk,Java,Swing,Ubuntu,Jlabel,Openjdk,因此,我编写了一个Java应用程序,它在屏幕顶部提供了一个透明的平视显示,它在windows上运行得非常好,但在我的kubuntu 16.04机器上,当您更改标签文本时,它不会清除旧标签,最终会导致大量重叠的混乱 因为一张图片胜过千言万语,顶部是它在窗口中的样子,底部是它在kubuntu下的样子: 代码如下: import java.util.*; import java.awt.*; import java.awt.event.*; import java.net.*; import jav

因此,我编写了一个Java应用程序,它在屏幕顶部提供了一个透明的平视显示,它在windows上运行得非常好,但在我的kubuntu 16.04机器上,当您更改标签文本时,它不会清除旧标签,最终会导致大量重叠的混乱

因为一张图片胜过千言万语,顶部是它在窗口中的样子,底部是它在kubuntu下的样子:

代码如下:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.net.URL;
import javax.swing.*;
import java.io.*;

public class spob extends JFrame implements WindowFocusListener
{
    public spob()
    {
        if (!SystemTray.isSupported()) {
            System.out.println("SystemTray is not supported");
            return;
        }
        final TrayIcon trayIcon = new TrayIcon((new ImageIcon("icon.png", "trayicon")).getImage());
        final SystemTray tray = SystemTray.getSystemTray();
        trayIcon.setImageAutoSize(true);
        trayIcon.setToolTip("spO2 pr monitor");        
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            System.out.println("TrayIcon could not be added.");
            return;
        }
        setType(javax.swing.JFrame.Type.UTILITY);
        setUndecorated(true);
        getContentPane().setBackground(new Color(1.0f,1.0f,1.0f,0.0f));
        setBackground(new Color(1.0f,1.0f,1.0f,0.0f));
        setSize(400, 35);
        JLabel label = new JLabel("Loading...");
        label.setFont(new Font("Tahoma", Font.BOLD, 28));
        label.setForeground(Color.GREEN);
        add(label);
        setLocation(800, 0);
        addWindowFocusListener(this);
        setAlwaysOnTop( true );
        this.setFocusable(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setVisible(true);
        URL url = null;
        BufferedReader in = null;
        String[] anArray = new String[10];
        anArray[0] = "<html><font color=green>- spO2:91  pr:65</font></html>";
        anArray[1] = "<html><font color=red>+ spO2:85  pr:77</font></html>";
        anArray[2] = "<html><font color=green>- spO2:90  pr:68</font></html>";
        anArray[3] = "<html><font color=orange>+ spO2:89  pr:76</font></html>";
        anArray[4] = "<html><font color=orange>- spO2:89  pr:72</font></html>";
        anArray[5] = "<html><font color=orange>+ spO2:88  pr:73</font></html>";
        anArray[6] = "<html><font color=red>- spO2:87  pr:78</font></html>";
        anArray[7] = "<html><font color=red>+ spO2:86  pr:73</font></html>";
        anArray[8] = "<html><font color=green>- spO2:92  pr:74</font></html>";
        anArray[9] = "<html><font color=green>+ spO2:90  pr:71</font></html>";
        while (true){
            try {
                Thread.sleep(200);
                //url = new URL("http://192.168.1.153/stat.php");
                //in = new BufferedReader(new InputStreamReader(url.openStream()));
                //label.setText(in.readLine().toString());
                Random randomno = new Random();
                label.setText(anArray[randomno.nextInt(9 - 1) + 1]);
            } catch (Exception ex) {
            } finally {
                //try {
                //  in.close();
                //} catch (IOException e) {
                //}
            }
        }
    }

    public void windowGainedFocus(WindowEvent e){}
    public void windowLostFocus(WindowEvent e)
    {
        if(e.getNewState()!=e.WINDOW_CLOSED){
            setAlwaysOnTop(false);
            setAlwaysOnTop(true);
        }

    }

    public static void main(String[] args) 
    {
    new spob();
    }
}
import java.util.*;
导入java.awt.*;
导入java.awt.event.*;
导入java.net。*;
导入java.net.URL;
导入javax.swing.*;
导入java.io.*;
公共类spob扩展JFrame实现WindowFocusListener
{
公共公共广播
{
如果(!SystemTray.isSupported()){
System.out.println(“不支持系统托盘”);
回来
}
final TrayIcon TrayIcon=new TrayIcon((new-ImageIcon(“icon.png”,“TrayIcon”)).getImage());
最终SystemTray=SystemTray.getSystemTray();
trayIcon.setImageAutoSize(真);
trayIcon.setToolTip(“spO2 pr监视器”);
试一试{
托盘。添加(trayIcon);
}捕获(awtexe){
System.out.println(“无法添加TrayIcon”);
回来
}
setType(javax.swing.JFrame.Type.UTILITY);
未装饰的设置(真实);
getContentPane().setBackground(新颜色(1.0f、1.0f、1.0f、0.0f));
收进背景(新颜色(1.0f、1.0f、1.0f、0.0f));
设置大小(400,35);
JLabel标签=新的JLabel(“加载…”);
label.setFont(新字体(“Tahoma”,Font.BOLD,28));
标签。设置前景(颜色。绿色);
添加(标签);
设置位置(800,0);
addWindowFocusListener(此);
setAlwaysOnTop(真);
此参数为.setFocusable(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(真);
URL=null;
BufferedReader in=null;
字符串[]anArray=新字符串[10];
anArray[0]=“spO2:91 pr:65”;
anArray[1]=“+spO2:85 pr:77”;
anArray[2]=“spO2:90 pr:68”;
anArray[3]=“+spO2:89 pr:76”;
anArray[4]=“spO2:89 pr:72”;
anArray[5]=“+spO2:88 pr:73”;
anArray[6]=“spO2:87 pr:78”;
anArray[7]=“+spO2:86 pr:73”;
anArray[8]=“spO2:92 pr:74”;
anArray[9]=“+spO2:90 pr:71”;
while(true){
试一试{
睡眠(200);
//url=新url(“http://192.168.1.153/stat.php");
//in=新的BufferedReader(新的InputStreamReader(url.openStream());
//label.setText(in.readLine().toString());
Random randomno=新的Random();
label.setText(anArray[randomno.nextInt(9-1)+1]);
}捕获(例外情况除外){
}最后{
//试一试{
//in.close();
//}捕获(IOE异常){
//}
}
}
}
公共无效windowGainedFocus(WindowEvent e){}
公共无效windowLostFocus(WindowEvent e)
{
如果(e.getNewState()!=e.WINDOW\u关闭){
setAlwaysOnTop(假);
setAlwaysOnTop(真);
}
}
公共静态void main(字符串[]args)
{
新spob();
}
}
所以,有一些问题

  • 您违反了Swing的单线程规则,本质上是从EDT上下文之外更新UI,如果系统试图在您尝试更新时绘制某些内容,这可能会导致问题
  • getContentPane().setBackground(新颜色(1.0f、1.0f、1.0f、0.0f))-Swing不知道如何处理基于alpha颜色的不透明组件,它倾向于不更新其下的任何组件
透明窗口是。。。享乐他们倾向于提出超出我们通常预期的自己的问题

在我的Mac系统上,我能够重现这个问题,但前后不一致。这一点尤其明显,因为Mac OS一直在文本周围渲染阴影

我摆脱的第一件事是
setType(javax.swing.JFrame.Type.UTILITY)
,我还添加了标签父容器的
重新绘制
请求,这似乎已经解决了问题的症状,但我仍然能够执行代码,有时不需要重新绘制

如果要定期更新UI,应使用Swing
计时器,有关详细信息,请参阅。如果需要在后台执行某些操作,然后更新UI,则应使用
SwingWorker
,查看更多详细信息

(哇,是我,它不喜欢我的动画gif:()

该示例故意使用半透明背景,旨在显示帧。将
pane.setAlpha(0.5f);
更改为
pane.setAlpha(0.0f);
使其完全透明(我也测试过)

如果有问题,请取消注释
计时器中的
label.getParent().repaint();
行,看看这是否有帮助

public class Test {

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

    private JLabel label;
    private String[] anArray = {
        "<html><font color=green>- spO2:91  pr:65</font></html>",
        "<html><font color=red>+ spO2:85  pr:77</font></html>",
        "<html><font color=green>- spO2:90  pr:68</font></html>",
        "<html><font color=orange>+ spO2:89  pr:76</font></html>",
        "<html><font color=orange>- spO2:89  pr:72</font></html>",
        "<html><font color=orange>+ spO2:88  pr:73</font></html>",
        "<html><font color=red>- spO2:87  pr:78</font></html>",
        "<html><font color=red>+ spO2:86  pr:73</font></html>",
        "<html><font color=green>- spO2:92  pr:74</font></html>",
        "<html><font color=green>+ spO2:90  pr:71</font></html>"
    };
    private Random randomno = new Random();

    public Test() {
        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("Testing");
                frame.setUndecorated(true);
                frame.setAlwaysOnTop(true);
                // Transparent window...
                frame.setBackground(new Color(255, 255, 255, 0));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                BackgroundPane pane = new BackgroundPane();
                // Set this to 0.0f to make it fully transparent
                pane.setAlpha(0.5f);
                pane.setLayout(new BorderLayout());

                pane.setBorder(new EmptyBorder(10, 10, 10, 10));

                frame.setContentPane(pane);

                label = new JLabel("Loading...");
                label.setFont(new Font("Tahoma", Font.BOLD, 28));
                label.setForeground(Color.GREEN);
                frame.add(label);

                frame.pack();
                Dimension size = frame.getSize();
                size.width = 400;
                frame.setSize(size);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(200, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        label.setText(anArray[randomno.nextInt(9 - 1) + 1]);
//                      label.getParent().repaint();
                    }
                });
                timer.start();
            }
        });
    }

    public class BackgroundPane extends JPanel {

        private float alpha;

        public BackgroundPane() {
            setOpaque(false);
        }

        public void setAlpha(float alpha) {
            this.alpha = alpha;
            repaint();
        }

        public float getAlpha() {
            return alpha;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(getBackground());
            g2d.setComposite(AlphaComposite.SrcOver.derive(getAlpha()));
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();
        }

    }

}

getContentPane().setBackground(新颜色(1.0f,1.0f,1.0f,0.0f))是您的问题,Swing不知道如何处理基于aloha颜色的不透明组件(JFrame是一个特例)。在您的情况下,只需创建一个新的JPanel实例,将其不透明状态设置为false,并将其作为内容面板应用于框架(并在需要时更新布局管理器)Swing也不是线程安全的,如果Swing,您的while循环将阻塞ETD或违反单线程规则。在这两种情况下,您都应该使用Swing Timerdo您的意思是,我将更新整个jpanel,而不是使用label.setText更新label?(使其在kubuntu上工作)…有趣的是,大部分代码都是通过互联网上的示例和文档组合而成的。当ETD被阻塞时会发生什么
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;

public class Test {

    public static void main(String[] args) {
        GraphicsEnvironment ge
                = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();

        boolean isUniformTranslucencySupported
                = gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT);
        boolean isPerPixelTranslucencySupported
                = gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT);
        boolean isShapedWindowSupported
                = gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT);

        System.out.println("isUniformTranslucencySupported = " + isUniformTranslucencySupported);
        System.out.println("isPerPixelTranslucencySupported = " + isPerPixelTranslucencySupported);
        System.out.println("isShapedWindowSupported = " + isShapedWindowSupported);
    }

}