Я пишу приложение, которое имеет JLayeredPane (называет его слоями), содержащее два JPanels в разных слоях. Я переопределяю метод paintComponent JPanel внизу (назовите его grid_panel), чтобы он рисовал сетку, и метод paintComponent того, что находится наверху (назовите его circuit_panel), чтобы он рисовал схему.JLayeredPane и painting
Вот краткое описание структуры:
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);
}
});
}
}
Я уверен, что вы не сможете обойти эту проблему, кроме, может быть, двойной буферизации ваши слои, если дорогой рисовать. Все сводится к RepaintManager, который отслеживает «грязные» регионы, потому что слои имеют одно и то же пространство экрана, а перекраска одного из них вызывает перерисовку другого ... Удачи. – Adam
Итак, есть способ для JPanel кэшировать то, что он должен рисовать (конечно, то, что было нарисовано, должно быть статическим) и позволить repaint() просто рисовать кеш, а не делать все эти вычисления снова и снова? – stackoverflower
hehehe on resize тоже, с ужасным мерцанием +1, должна быть другая проблема, но можете ли вы использовать [JLayer (начиная с Java7)] (http://stackoverflow.com/a/9272534/714968) или 'JXLayer (для Java6) ' – mKorbel