Tôi đang viết một ứng dụng có JLayeredPane (gọi nó là lớp) chứa hai JPanels ở các lớp khác nhau. Tôi ghi đè lên phương pháp paintComponent của JPanel ở phía dưới (gọi nó là grid_panel) để nó vẽ một lưới, và phương thức paintComponent của một ở đầu (gọi nó là circuit_panel) để nó vẽ một mạch.JLayeredPane và vẽ
Dưới đây là một bản tóm tắt của cấu trúc:
layers -
|-circuit_panel (on top)
|-grid_panel (at bottom)
Tôi muốn grid_panel ở lại tĩnh, tức là, không phải làm bất cứ repaint (trừ ban đầu một) vì nó không thay đổi.
Sự cố là, bất cứ khi nào tôi gọi circuit_panel.repaint(), grid_panel cũng được sơn lại! Đây chắc chắn là không hiệu quả.
Tôi nghĩ điều này là do hành vi sơn mong muốn của JLayeredPane. Có cách nào để tắt tính năng này trong JLayeredPane không?
Trong trường hợp bạn đang quan tâm để xem hiệu ứng trên, tôi đã viết một chương trình giới thiệu nhỏ:
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);
}
});
}
}
Tôi khá chắc chắn rằng bạn sẽ không thể làm được việc này ngoài việc có thể tăng gấp đôi đệm lớp của bạn nếu tốn kém để vẽ. Tất cả đi xuống để RepaintManager mà theo dõi các khu vực "bẩn", bởi vì các lớp chia sẻ cùng một không gian màn hình một repaint của một sẽ kích hoạt một repaint khác ... Chúc may mắn. – Adam
Vì vậy, có cách nào để JPanel lưu vào bộ nhớ cache những gì nó nên vẽ (tất nhiên những gì được vẽ nên tĩnh), và để vẽ lại() để vẽ bộ nhớ cache, thay vì thực hiện tất cả các phép tính đó lặp đi lặp lại? – stackoverflower
hehehe về thay đổi kích thước quá, với khủng khiếp nhấp nháy +1, phải có một vấn đề khác, nhưng bạn có thể sử dụng [JLayer (kể từ Java7)] (http://stackoverflow.com/a/9272534/714968) hoặc 'JXLayer (cho Java6) ' – mKorbel