简体   繁体   English

当我从另一个类更新时,为什么“javax.swing.JProgressBar”在旧值之上显示新值?

[英]Why “javax.swing.JProgressBar” displays new values on top of old values when I update from another class?

Problem: 问题:

ClassA
    static JProgressBar progressBar;
ClassB
    ClassA.progressBar.setValue(0);
    ...
    ClassA.progressBar.setValue(10);
    ...
    ClassA.progressBar.setValue(20);

Progress bar displays 0, then 10 on top of the 0, then 20 on top of the 10. 进度条显示0,然后在0的顶部显示10,然后在10的顶部显示20。

Code: 码:

public class ClassA
{
    static JProgressBar progressBar;
    public ClassA()
    {
        ...
        progressBar = new JProgressBar(0, 100);
        progressBar.setStringPainted(true);
        ...
    }
    public static void main(String[] args)
    {
        ClassA cA = new ClassA();
        cA.something();
    }
    public void something()
    {
        ...
        panel.add(progressBar, BorderLayout.CENTER);
        ...
    }
    ...
}
public class ClassB
{
    public void something()
    {
        ...
        ClassA.progressBar.setValue(0);
        ClassA.progressBar.update(ClassA.progressBar.getGraphics());
        ...
    }
    ...
}

I am also adding the progress bar to the panel. 我还在面板中添加了进度条。 As it was mentioned above, it displays the progress bar and the percentage but it show each value on top of another. 如上所述,它显示进度条和百分比,但它显示每个值在另一个之上。

EDIT: The problem is very similar to this: Java Swing revalidate() vs repaint() . 编辑:问题非常类似于: Java Swing revalidate()vs repaint() However, instead of 但是,而不是

the old content is still actually visible (though obscured by the the new content) 旧内容仍然可见(虽然被新内容遮盖)

being problem with JPanel, mine is problem with JProgressBar. 由于JPanel存在问题,我的问题是JProgressBar。 I tried ClassA.progressBar.revalidate(); 我试过ClassA.progressBar.revalidate(); and ClassA.progressBar.repaint(); ClassA.progressBar.repaint(); but nothing works except ClassA.progressBar.update(ClassA.progressBar.getGraphics()); 但除了ClassA.progressBar.update(ClassA.progressBar.getGraphics());之外没有任何作用ClassA.progressBar.update(ClassA.progressBar.getGraphics()); , which, again, as it was mentioned above, displays new values on top of old values. ,再次,如上所述,在旧值之上显示新值。

You don't need this line: 你不需要这一行:

ClassA.progressBar.update(ClassA.progressBar.getGraphics());

Calling setValue() will update the progress bar UI. 调用setValue()将更新进度条UI。

Otherwise there is nothing wrong with the code you posted here. 否则,您在此处发布的代码没有任何问题。 The issue must lie elsewhere. 问题必须在其他地方。 Here's a SSCCE based on your code, which works as expected with no paint issues. 这是一个基于您的代码的SSCCE,它按预期工作,没有油漆问题。

public class ClassA {
    static JProgressBar progressBar;
    private ClassB classb;
    private JPanel panel;


    public ClassA() {
        progressBar = new JProgressBar(0, 100);
        progressBar.setStringPainted(true);

        classb = new ClassB();

        JButton button = new JButton("test");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                classb.something();
            }
        });

        panel = new JPanel();
        panel.add(button);
        panel.add(progressBar, BorderLayout.CENTER);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }


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

public class ClassB
{
    private int index;

    public void something()
    {
        ClassA.progressBar.setValue(++index);
        //ClassA.progressBar.update(ClassA.progressBar.getGraphics());
    }
}

Arthur, your code snippet doesn't show how ClassB.something gets called. Arthur,你的代码片段没有显示如何调用ClassB.something。 Most of Swing is not thread safe and unless the javadoc explicitly states otherwise, Swing ui components need to be modified from the Event Dispatch Thread. 大多数Swing都不是线程安全的,除非javadoc明确指出,否则需要从Event Dispatch Thread修改Swing ui组件。 Usually if a Swing component is thread-safe it explicitly calls this out in the javadoc. 通常,如果Swing组件是线程安全的,它会在javadoc中显式调用它。 I took a look at the JProgressBar javadoc and saw no disclaimer, actually it has a warning that Swing is not threadsafe. 我看了一下JProgressBar javadoc并没有看到免责声明,实际上它有一个警告 ,Swing不是线程安全的。
If Swing components are accessed from other threads it can cause applications to behave strangely. 如果从其他线程访问Swing组件,则可能导致应用程序出现奇怪的行为。 I've seen components render strangely and incompletely because of improper threading. 我看到由于线程不正确,组件呈现奇怪且不完整。 If ClassA is going to construct and modify swing components in the constructor, the constructor should get executed from the Event Dispatch Thread. 如果ClassA要在构造函数中构造和修改swing组件,那么构造函数应该从Event Dispatch Thread执行。

public class ClassA 
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new ClassA());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM