优化容器中数百个组件的绘制

问题描述 投票:0回答:1

我的应用程序有一个钢琴卷轴音乐编辑器,它使用类似于下面的代码来更改可能数百个小矩形组件(音符)的背景颜色。它太慢了,你可以清楚地看到各个方块的切换。

如何优化?

public class TestManyChildrenRepaint {

  public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        
      // Container with many square panels in a grid
      final int NB_SQUARES = 70;
      JPanel squareContainer = new JPanel(new GridLayout(NB_SQUARES, NB_SQUARES, 1, 1));
      List<Square> squares = new ArrayList<>();
      for (int i=0; i < NB_SQUARES * NB_SQUARES; i++) {
        var s = new Square();
        squareContainer.add(s);
        squares.add(s);
      }


      // Toggle selection of all squares
      JButton toggle = new JButton("Toggle");
      toggle.addActionListener(e -> squares.forEach(s -> s.toggleSelection()));


      // Build JFrame
      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setLayout(new BorderLayout());
      frame.add(toggle, BorderLayout.WEST);
      frame.add(squareContainer, BorderLayout.EAST);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
    });
  }

  private static class Square extends JPanel {

    private boolean selected;

    public Square() {
      setPreferredSize(new Dimension(10, 10));
      setSelected(false);
    }

    public void toggleSelection() {
      setSelected(!selected);
    }

    public void setSelected(boolean b) {
      selected = b;
      setBackground(selected ? Color.BLUE : Color.ORANGE);
    }
  }
java swing
1个回答
0
投票

明白了。用这个最小的例子更容易破解。

repaint()
setBackground()
调用,这会生成太多对
repaint()
的调用。

我添加了一个

Square.paintComponent()
方法,该方法根据选择状态绘制背景。这样我就可以更改
Square
背景值,而无需调用
repaint()
。只有在所有单独的方块都更新完毕后,我才会调用
squareContainer.repaint()

© www.soinside.com 2019 - 2024. All rights reserved.