JLayeredPane和绘画

我正在编写一个应用程序,它有一个JLayeredPane(称之为图层),包含两个不同层的JPanel。 我覆盖了底部JPanel的paintComponent方法(称之为grid_panel),因此它绘制了一个网格,并在顶部绘制了一个paintComponent方法(称之为circuit_panel),因此它绘制了一个电路。

以下是结构摘要:

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

我希望grid_panel保持静态,即不进行任何重绘(除了初始的重绘),因为它不会改变。

麻烦的是, 每当我调用circuit_panel.repaint()时,grid_panel也会被重新绘制! 这绝对不是有效的。

我认为这是由于JLayeredPane的热切绘画行为。 有没有办法在JLayeredPane中禁用此function?

如果你有兴趣看到上述效果,我写了一个小的演示程序:

 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就是一个例子。 这里显示的flyweight渲染器是另一种方法。 最后,我以一种可以使实验更容易的方式重新考虑了你的指导性例子。

图层演示

 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); } }); } }