问题描述
有没有办法在 Java 中创建一个分层的组件系统,以便在某一时刻只更新(重绘)一层?
最简单的示例是一张大地图,其中包含数以千计的形状和标签,这些形状和标签将放置在“底部”图层上。在“顶层”层上还有另一个小形状,自定义工具提示将是这种情况的一个很好的例子。现在,只要工具提示的位置更新(通过鼠标移动),即使您只在该组件上专门调用 repaint(),整个框架也会更新(因此在每一层上调用重绘,使整个系统变得非常慢且无效)。
我知道您可以通过将内容缓存为图像并绘制图像而不是数千个形状来实现一些优化,但是,我仍然对“更简单”的解决方案感兴趣。
谢谢。
示例代码:
基本上有一个主框架 (m),它加载一个容器 (mc),这个容器有两个“层”(ml)。现在,当我只为第二层调用 repaint() 时,很容易看到所有的paintComponent() 都被再次调用(控制台文本出现,但两个矩形都将颜色更改为新的随机矩形)。这就是我需要防止的。
文件:m.java
import javax.swing.JFrame;
import java.awt.EventQueue;
import java.util.Timer;
import java.util.TimerTask;
public class m extends JFrame {
public mc omc;
public m() {
initUI();
}
private void initUI() {
this.pack();
this.setSize(600,680);
this.setResizable(true);
this.setLocationRelativeto(null);
this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.omc = new mc();
this.add(omc);
m self = this;
Timer oTimer = new Timer();
oTimer.schedule(new TimerTask() {
@Override
public void run() {
self.omc.oml1.repaint();
}
},2000);
}
public static void main(String[] args) {
EventQueue.invokelater(new Runnable() {
public void run() {
m ex = new m();
ex.setVisible(true);
}
});
}
}
文件:mc.java
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import java.awt.Graphics;
public class mc extends JPanel {
public ml oml0;
public ml oml1;
public mc() {
this.setLayout(new OverlayLayout(this));
this.oml0 = new ml(0);
this.oml1 = new ml(1);
this.add(oml0);
this.add(oml1);
}
public void paintComponent(Graphics g) {
System.out.println("mc");
super.paintComponent(g);
}
}
文件:ml.java
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
public class ml extends JPanel {
private int l = 0;
public ml(int ll) {
this.l = ll;
this.setopaque(false);
}
public void paintComponent(Graphics g) {
System.out.println("ml:" + this.l);
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
if (this.l == 0) {
g2d.setPaint(new Color((int)Math.round(100 + 150 * Math.random()),(int)Math.round(100 + 150 * Math.random()),(int)Math.round(100 + 150 * Math.random())));
g2d.fillRect(30,30,300,100);
}
if (this.l == 1) {
g2d.setPaint(new Color((int)Math.round(100 + 150 * Math.random()),(int)Math.round(100 + 150 * Math.random())));
g2d.fillRect(130,80,100);
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)