【问题标题】:Bad rendering onUpdate Swing component Java错误渲染 onUpdate Swing 组件 Java
【发布时间】:2015-11-28 00:02:27
【问题描述】:

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

对不起,我的英语不好。

这是右侧和左侧数字的正确呈现方式

这是我点击某个按钮然后执行一些OnUpdate()时的渲染

编辑 这是包含 JLabels 的 JPanel 类:

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();
    }
}

【问题讨论】:

  • 人们会建议您提供代码示例,以便我们更好地了解问题所在。我的第一个猜测可能与repaint() 有关
  • 如果我只在 JLabels 上调用 repaint() ,情况不会改变。如果我在包含 JLabels 的面板中调用 repaint(),则整个 JPanel 的渲染是错误的。
  • @Miggianox 正如 Gorbles 已经提到的,如果没有合适的 minimal reproducible example,我们可能无法为您提供帮助。请考虑提供一个以便更快地获得更好的帮助。
  • 在您发布的小片段@Miggianox 中,您似乎使用了很多(不必要的?)静态声明。请考虑发布更完整的代码示例。

标签: java swing rendering


【解决方案1】:

所有变量名的开头不应以大写字符开头。您的代码很难阅读,因为论坛认为您的所有变量都是类名并突出显示它们。遵循 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 了解更多信息和更简单的解决方案,这样您就无需对所有组件进行自定义绘制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 2013-01-04
    • 2013-02-02
    • 1970-01-01
    • 2014-08-29
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多