糟糕的渲染onUpdate Swing组件Java

时间:2015-11-27 13:22:06

标签: java swing rendering

我在Java中使用JLabel时出现渲染问题: 我使用模式oberver observable,当我的模型通知我的View时,JLabel已经改变了JLabel的内容,或者特别是我的JLabel区域中显示的内容是随机的。有时它会渲染另一个面板中的按钮的一部分,或者有时会呈现我在视图的其他组件中设置的颜色! 但如果我最小化然后最大化我的框架,所有都被正确渲染。

抱歉我的英语不好。

这是右侧和左侧数字的正确呈现 enter image description here

当我点击某个按钮然后执行某些OnUpdate() 时,这是渲染 enter image description here

修改 这是我的JPanel的类包含JLabel:

class InformationPanel extends JPanel {

    private static final int DEFAULT_INFO_WIDTH = Configuration.DEFAULT_INFO_PANEL_WIDTH;
    private static final int DEFAULT_INFO_HEIGHT = Configuration.DEFAULT_INFO_PANEL_HEIGHT;

    private String playerId;
    private int numNaviVive;
    private int numNaviAffondate;
    private JLabel JLabelNumNaviAffondate;
    private JLabel JLabelNumNaviVive;

    public InformationPanel(String playerId) {
        this.playerId = playerId;
        numNaviVive = 0;
        numNaviAffondate = 0;

        JButton JButtonPlayerId = new JButton(playerId);
        JLabelNumNaviAffondate = new JLabel(String.valueOf(numNaviAffondate));
        JLabelNumNaviVive = new JLabel(String.valueOf(numNaviVive));
        JLabel JlblNumNaviVive = new JLabel("Navi disponibili:");
        JLabel JlblNumNaviAffondate = new JLabel("Navi affondate: ");

        JButtonPlayerId.setBackground(new Color(0, 0, 0, 0));
        JButtonPlayerId.setFont(new Font("Serif", Font.BOLD, 16));
        JButtonPlayerId.setForeground(Color.YELLOW);
        JButtonPlayerId.setFocusable(false);
        JButtonPlayerId.setEnabled(false);

        JlblNumNaviVive.setBackground(new Color(0, 0, 0, 0));
        JlblNumNaviVive.setFont(new Font("Serif", Font.BOLD, 16));
        JlblNumNaviVive.setForeground(Color.YELLOW);
        JlblNumNaviVive.setDoubleBuffered(true);

        JlblNumNaviAffondate.setBackground(new Color(0, 0, 0, 0));
        JlblNumNaviAffondate.setFont(new Font("Serif", Font.BOLD, 16));
        JlblNumNaviAffondate.setForeground(Color.YELLOW);
        JlblNumNaviAffondate.setDoubleBuffered(true);

        JLabelNumNaviAffondate.setBackground(new Color(0, 0, 0, 0));
        JLabelNumNaviAffondate.setFont(new Font("Serif", Font.BOLD, 16));
        JLabelNumNaviAffondate.setForeground(Color.YELLOW);
        JLabelNumNaviAffondate.setFocusable(false);
        JLabelNumNaviAffondate.setEnabled(false);

        JLabelNumNaviVive.setBackground(new Color(0, 0, 0, 0));
        JLabelNumNaviVive.setFont(new Font("Serif", Font.BOLD, 16));
        JLabelNumNaviVive.setForeground(Color.YELLOW);
        JLabelNumNaviVive.setFocusable(false);
        JLabelNumNaviVive.setEnabled(false);

        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        setPreferredSize(new Dimension(DEFAULT_INFO_WIDTH, DEFAULT_INFO_HEIGHT));
        //setBackground(new Color(0, 0, 0, 0));
        setBackground(new Color(0,0,0,40));

        add(JButtonPlayerId);
        add(JlblNumNaviAffondate);
        add(JLabelNumNaviAffondate);
        add(JlblNumNaviVive);
        add(JLabelNumNaviVive);
        setVisible(true);
    }

    public String getId() {
        return playerId;
    }

    public int getNumNaviAffondate() {
        return numNaviAffondate;
    }

    public int getNumNaviVive() {
        return numNaviVive;
    }

    public void setNumNaviVive(int numNaviVive) {
        this.numNaviVive = numNaviVive;
        this.JLabelNumNaviVive.setText(String.valueOf(numNaviVive));
        this.validate();

    }

    public void setNumNaviAffondate(int numNaviAffondate) {
        this.numNaviAffondate = numNaviAffondate;
        this.JLabelNumNaviAffondate.setText(String.valueOf(numNaviAffondate));
        this.validate();
    }
}

1 个答案:

答案 0 :(得分:2)

所有变量名称的首字母不应以大写字母开头。您的代码很难阅读,因为论坛认为您的所有变量都是类名并且会突出显示它们。遵循Java惯例,不要自己编写。

JLabelNumNaviAffondate.setBackground(new Color(0, 0, 0, 0));

默认情况下,变量是透明的,因此您无法为它们设置背景颜色。您尝试设置透明颜色的事实可能是也可能不是您的问题。

setBackground(new Color(0,0,0,40));

这可能是问题所在。你不能只在Swing组件上设置透明度,因为这会破坏绘画链。这是一个不透明的组件,可以保证自己绘制背景,但是当你使用透明度时,背景并没有被完全绘制,所以你会得到绘画文物。

所以基本上你需要自己管理背景的绘画。因此,您实际上需要首先绘制对父组件不透明的组件,然后您可以绘制透明背景。

JPanel panel = new JPanel()
{
    protected void paintComponent(Graphics g)
    {
        g.setColor( getBackground() );
        g.fillRect(0, 0, getWidth(), getHeight());
        super.paintComponent(g);
    }
};
panel.setOpaque(false);
panel.setBackground( new Color(255, 0, 0, 20) );
frame.add(panel);

有关详细信息和更简单的解决方案,请参阅Background With Transparency,以便您无需在所有组件上进行自定义绘制。