当前位置: 首页 > 知识库问答 >
问题:

更新Swing组件Java上的渲染错误

濮阳研
2023-03-14

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

对不起,我的英语不好。

EDIT这是我的JPanel的类,其中包含JLabels:

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个答案

白宏大
2023-03-14

所有变量名的第一个不应该以大写字符开头。你的代码很难阅读,因为论坛认为你所有的变量都是类名,并以此突出显示。遵循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);

有关更多信息和更简单的解决方案,请参阅透明背景,这样您就不需要对所有组件进行自定义绘制。

 类似资料:
  • 我试图用ajax更新一个有条件渲染的组件。 但是,这不起作用。我可以保证实际上是可用的。这是如何造成的,我如何解决它?

  • 我对react还比较陌生,我一直在分解一个web应用程序,并用react组件替换部分。我现在正在开发一个组件,其中包含我创建的几个不同组件。 在新组件中,我在componentDidMount函数中进行API调用,并创建子组件。乍一看,一切看起来都很完美,但当我们在其中一个子组件中进行状态更改,然后在父组件中进行更改时,子组件将其状态重置为更改之前的状态。 我知道发生了什么,州政府没有被传递给家长

  • 问题内容: 我正在使用Preact(出于所有意图和目的,React)来渲染保存在状态数组中的项目列表。每个项目旁边都有一个删除按钮。我的问题是:单击该按钮时,将删除正确的项目(我已对此进行了几次验证),但是重新渲染项目时缺少 最后一个 项目,并且删除的项目仍然存在。我的代码(简体): 我究竟做错了什么?我是否需要以某种方式主动重新渲染?这是n + 1种情况吗? 澄清 :我的问题不在于国家的同步性。

  • 使用jsf 2和Primeface 3.4 我知道有许多类似的问题,但没有一个能解决这个问题。 当面板网格“内部”以固定值“true”呈现时(

  • 当我每500毫秒调用来显示更新的图表时,我面临着呈现问题。我使用上的创建了大约30个Barchart。 有错误的渲染和我如何解决这个问题? 此代码每500毫秒调用一次,是使用的信息在上构建图表的函数。

  • 问题内容: 我正在尝试将表示性组件与容器组件分开。我有一个和一个。容器负责触发redux操作,以根据当前用户获取适当的网站。 问题是在最初呈现容器组件之后,异步获取了当前用户。这意味着容器组件不知道它需要重新执行其函数中的代码,该代码将更新数据以发送到。我认为我需要在其props(user)之一更改时重新渲染容器组件。如何正确执行此操作? 问题答案: 您必须在方法中添加条件。 该示例用于比较对象。