Java Swing - 高度 CPU 用法

Java Swing - hight CPU usage

Java 摆动 - 高 CPU 用法

我有两个组件 classes 覆盖了 public void paint(Graphics g) 方法。
类:

    public abstract class DragItemComp extends JPanel {
        private MouseAdapter butListener = new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                ...
                possibleList = new JFrame();
                possibleList.setAlwaysOnTop(true);
                possibleList.setType(Type.UTILITY);
                ...
                setPreferredSize(neededSize);
            }
        };
        public JFrame possibleList;
        public DragItemComp() {
            setBackground(new Color(0, 0, 0, 0));
            createComps();
            addMouseListener(butListener);
            f = new Font(getFont().getFontName(), Font.BOLD, 14);
        }
        public void createComps(){
            removeAll();
            int h = 0;
            for (ConnectPoint connectPoint : blueVisible) {
                connectPoint.setLocation(0, h);
                h += connectPoint.getHeight()+6; 
            }
        }
        public void onMove(){
            if(possibleList == null || !possibleList.isVisible())
                return;
            
            //calculating stuff
            possibleList.setLocation(newPoint);
            possibleList.repaint();
            System.gc();
            //updating fields
        }
        @Override
        public void paint(Graphics g) {
            super.paint(g);
            //...;
            g.setFont(new Font(...));
            //...
            setPreferredSize(neededSize);
            System.gc();
        }
        public class ConnectPoint extends JPanel{
            private Font f; 
            public ConnectPoint(String text,Runnable onClick)
            {
                ...
                setSize(text.length()*getFont().getSize()+20, 15);
                addMouseListener(new MouseAdapter(){
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        System.out.println("Click");
                        new Thread(onClick).start();
                        DragItemComp.this.redPossible.remove(this);
                        DragItemComp.this.redVisible.add(ConnectPoint.this);
                    }
                });
                //adding key listener
            }
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                if(out)
                    g.setColor(Color.RED);
                else
                    g.setColor(Color.BLUE);
                g.fillOval(0, 0, 10, 10);
                g.setColor(Color.BLACK);
                g.setFont(f);
                g.drawString(text, 15, 11);
            }
            //interface method implementations cut out
        }
    }

我知道这是很多代码,对此我深表歉意(编辑:减少了大量代码)。
我怀疑这个 class 可能会导致问题

public class JavaScriptDropFileComponent extends JPanel {
    //fields
    public JavaScriptDropFileComponent() {
        setLayout(new GridLayout(0, 1, 0, 0));
        placeFrame = new JFrame();
        //...
        new Thread(()->{
            while(isVisible()){
                Thread.sleep(10000);
                if(nextPlace == null || !tryIt.isVisible()){
                    continue;
                }
                if(some_condition) {
                    if(placeFrame.isVisible())
                        placeFrame.setVisible(false);
                    continue;
                }
                else{
                    if(!placeFrame.isVisible())
                        placeFrame.setVisible(true);
                }
                placeFrame.setLocation(/*some computet point (just a few multiplications*/);
                if(condition)
                    placeFrame.setSize(justSomrDimension);
            }
            
        }).start();
    }
}

为了缩短,我删除了 getter/setter、导入、字段和非信息代码。 (编辑:我进一步删除了代码,并替换了一些不相关的条件等)

那么为什么它需要这么多 CPU 我该如何改变它?

另一个有趣的事实是 CPU 用法不依赖于线程的休眠时间。我尝试了 100000、1000、10、1 毫秒。它没有改变任何东西!

uploaded所有你需要执行的classes。 -> DragTester.java 是主要的 class.
可能您需要更改“包 com.niton.**”贴标。
我更新了代码以减少 CPU.

简单的答案是:不要在 paint 方法中做超出绝对必要的工作。

一眼看去,每次调用 paint 时,您都在创建一个新的 Font 并调用 setPreferredSize。

一次创建您的字体并缓存它并从您的绘画方法中引用它。

此外,在您的绘画方法之外调用 setPreferredSize。