JLayeredPane и рисование

Я пишу приложение, которое имеет JLayeredPane (назовите его слоями), содержащий два JPanels в разных слоях. Я переопределяю метод paintComponent JPanel внизу (назовите его grid_panel), чтобы он рисовал сетку, и метод paintComponent того, что находится наверху (назовите его circuit_panel), чтобы он рисовал схему.

Вот краткое описание структуры:

layers - |-circuit_panel (on top) |-grid_panel (at bottom) 

Я хочу, чтобы grid_panel оставался статичным, т. Е. Не перерисовывать (кроме исходного), так как он не изменяется.

Проблема в том, что всякий раз , когда я вызываю circuit_panel.repaint (), grid_panel также перекрашивается! Это определенно неэффективно.

Я думаю, что это связано с нетерпеливым поведением JLayeredPane. Есть ли способ отключить эту функцию в JLayeredPane?

Если вам интересно увидеть вышеупомянутый эффект, я написал небольшую демонстрационную программу:

 public class Test2 extends JFrame { public Test2() { JLayeredPane layers = new JLayeredPane(); layers.setPreferredSize(new Dimension(600, 400)); MyPanel1 myPanel1 = new MyPanel1(); MyPanel2 myPanel2 = new MyPanel2(); myPanel1.setSize(600, 400); myPanel2.setSize(600, 400); myPanel1.setOpaque(false); myPanel2.setOpaque(false); myPanel2.addMouseListener(new MyMouseListener(myPanel2)); layers.add(myPanel1, new Integer(100)); // At bottom layers.add(myPanel2, new Integer(101)); // On top this.getContentPane().add(layers, BorderLayout.CENTER); this.setSize(600, 400); } class MyPanel1 extends JPanel { Color getRandomColor() { int r = (int) (256 * Math.random()); int g = (int) (256 * Math.random()); int b = (int) (256 * Math.random()); return new Color(r, g, b); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(getRandomColor()); g2d.fillRoundRect(30, 30, 60, 60, 5, 5); } } class MyPanel2 extends JPanel { Color getRandomColor() { int r = (int) (256 * Math.random()); int g = (int) (256 * Math.random()); int b = (int) (256 * Math.random()); return new Color(r, g, b); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setColor(getRandomColor()); g2d.fillRoundRect(45, 45, 75, 75, 5, 5); } } class MyMouseListener extends MouseAdapter { JPanel panel; MyMouseListener(JPanel panel) { this.panel = panel; } @Override public void mouseClicked(MouseEvent e) { panel.repaint(); } } /** * @param args */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { (new Test2()).setVisible(true); } }); } } 

Как вы нашли, BufferedImage – эффективный способ кэширования сложного контента для эффективного рендеринга; CellTest . Представленный здесь визуализатор мухи – это еще один подход. Наконец, я переустановил ваш поучительный пример таким образом, чтобы упростить эксперименты.

Демо-версия

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Random; import javax.swing.JFrame; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; /** @see https://stackoverflow.com/q/9625495/230513 */ public class LayerDemo extends JFrame { private static final Dimension d = new Dimension(320, 240); public LayerDemo() { JLayeredPane layers = new JLayeredPane(); layers.setPreferredSize(d); layers.add(new LayerPanel(1 * d.height / 8), 100); layers.add(new LayerPanel(2 * d.height / 8), 101); layers.add(new LayerPanel(3 * d.height / 8), 102); this.add(layers, BorderLayout.CENTER); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.pack(); this.setLocationByPlatform(true); } private static class LayerPanel extends JPanel { private static final Random r = new Random(); private int n; private Color color = new Color(r.nextInt()); public LayerPanel(int n) { this.n = n; this.setOpaque(false); this.setBounds(n, n, d.width / 2, d.height / 2); this.addMouseListener(new MouseHandler(this)); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(color); g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 16, 16); g2d.setColor(Color.black); g2d.drawString(String.valueOf(n), 5, getHeight() - 5); } private void update() { color = new Color(r.nextInt()); repaint(); } } private static class MouseHandler extends MouseAdapter { LayerPanel panel; MouseHandler(LayerPanel panel) { this.panel = panel; } @Override public void mouseClicked(MouseEvent e) { panel.update(); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { (new LayerDemo()).setVisible(true); } }); } } 
  • Обновление образа, содержащегося в JLabel, - проблемы
  • Как я могу обновить внешний вид JFreeChart после того, как он станет видимым?
  • Воспроизведение изменения значения в JTextField
  • Поместите JTable в JTree
  • Список свойств интерфейса Java Swing?
  • Сделать JScrollPane управление несколькими компонентами
  • Как изменить цвет JProgressBar?
  • Множество изображений JLabel
  • Масштабируйте ImageIcon автоматически до размера метки
  • Сделать кнопку круглой
  • Как правильно использовать собственные средства визуализации для рисования конкретных ячеек в JTable?
  • Давайте будем гением компьютера.