import javax.swing.*;
import java.awt.event.*;
import java.awt.FlowLayout;
import java.awt.Dimension;
import java.lang.String;
import javax.swing.JOptionPane;
import java.awt.Container;
import java.util.Hashtable;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
class ComboBoxRenderer
implements ListCellRenderer { public ComboBoxRenderer() {
} public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel itemLabel = new JLabel(value);
JPanel itemPanel = new JPanel();
itemPanel.setToolTipText(sValue);
itemPanel.setSize(list.getSize().width, 25);
itemPanel.setLayout(new BorderLayout());
itemPanel.add(itemLabel, BorderLayout.WEST);
if (isSelected || cellHasFocus) {
itemPanel.setForeground(list.getSelectionForeground());
itemPanel.setBackground(list.getSelectionBackground());
}
else {
itemPanel.setForeground(list.getForeground());
itemPanel.setBackground(list.getBackground());
}
return itemPanel;
}
}
public class test extends JFrame{
JComboBox select=null;
JButton button=null;
consuMem mem=null;
String preItem=null;
Hashtable sessionTable=new Hashtable();
public test(String title) {
super(title);
setSize(new Dimension(200,100));
getContentPane().setLayout(new FlowLayout());
addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
} });
select=new JComboBox();
select.setRenderer(
new ComboBoxRenderer(ComboBoxRenderer.COMBOTYPE_TEMPLATE));
for (int i=0;i<200;i++) {
select.addItem(String.valueOf(i));
}
select.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
}
});
getContentPane().add(select); }
public static void main(String[] args) {
sessionWindow swindow=null;
test test1=new test("MainWindow");
test1.show();
}
}
以上程序主要是自己实现一个ListCellRenderer类,调试,用键盘在combobox的item中反复上下切换,观察内存继续增长,怀疑是 JLabel itemLabel = new JLabel(value);
JPanel itemPanel = new JPanel();
这两句的问题,因为它们每次都会分配新的对象,于是将ComboBoxRenderer类改为如下形式:
class ComboBoxRenderer
implements ListCellRenderer {
public static JLabel itemLabel = new JLabel();
public static JPanel itemPanel = new JPanel();
private int type_; public ComboBoxRenderer(int type) {
} public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
if (value == null) {
return null;
}
itemLabel.setText(value);
itemPanel.setToolTipText(sValue);
itemPanel.setSize(list.getSize().width, 25);
itemPanel.setLayout(new BorderLayout());
itemPanel.add(itemLabel, BorderLayout.WEST);
if (isSelected || cellHasFocus) {
itemPanel.setForeground(list.getSelectionForeground());
itemPanel.setBackground(list.getSelectionBackground());
}
else {
itemPanel.setForeground(list.getForeground());
itemPanel.setBackground(list.getBackground());
}
return itemPanel;
}
}
发现不会出现上面的现象了。但是我不大理解为什么会这样,按道理说,JVM每次getListCellRendererComponent()绘制完后,对它们的引用就会消失,内存也会被回收,为什么会出现上面的现象内,哪位大侠能够给解释一下,谢谢了
import java.awt.event.*;
import java.awt.FlowLayout;
import java.awt.Dimension;
import java.lang.String;
import javax.swing.JOptionPane;
import java.awt.Container;
import java.util.Hashtable;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
class ComboBoxRenderer
implements ListCellRenderer { public ComboBoxRenderer() {
} public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel itemLabel = new JLabel(value);
JPanel itemPanel = new JPanel();
itemPanel.setToolTipText(sValue);
itemPanel.setSize(list.getSize().width, 25);
itemPanel.setLayout(new BorderLayout());
itemPanel.add(itemLabel, BorderLayout.WEST);
if (isSelected || cellHasFocus) {
itemPanel.setForeground(list.getSelectionForeground());
itemPanel.setBackground(list.getSelectionBackground());
}
else {
itemPanel.setForeground(list.getForeground());
itemPanel.setBackground(list.getBackground());
}
return itemPanel;
}
}
public class test extends JFrame{
JComboBox select=null;
JButton button=null;
consuMem mem=null;
String preItem=null;
Hashtable sessionTable=new Hashtable();
public test(String title) {
super(title);
setSize(new Dimension(200,100));
getContentPane().setLayout(new FlowLayout());
addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
} });
select=new JComboBox();
select.setRenderer(
new ComboBoxRenderer(ComboBoxRenderer.COMBOTYPE_TEMPLATE));
for (int i=0;i<200;i++) {
select.addItem(String.valueOf(i));
}
select.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
}
});
getContentPane().add(select); }
public static void main(String[] args) {
sessionWindow swindow=null;
test test1=new test("MainWindow");
test1.show();
}
}
以上程序主要是自己实现一个ListCellRenderer类,调试,用键盘在combobox的item中反复上下切换,观察内存继续增长,怀疑是 JLabel itemLabel = new JLabel(value);
JPanel itemPanel = new JPanel();
这两句的问题,因为它们每次都会分配新的对象,于是将ComboBoxRenderer类改为如下形式:
class ComboBoxRenderer
implements ListCellRenderer {
public static JLabel itemLabel = new JLabel();
public static JPanel itemPanel = new JPanel();
private int type_; public ComboBoxRenderer(int type) {
} public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
if (value == null) {
return null;
}
itemLabel.setText(value);
itemPanel.setToolTipText(sValue);
itemPanel.setSize(list.getSize().width, 25);
itemPanel.setLayout(new BorderLayout());
itemPanel.add(itemLabel, BorderLayout.WEST);
if (isSelected || cellHasFocus) {
itemPanel.setForeground(list.getSelectionForeground());
itemPanel.setBackground(list.getSelectionBackground());
}
else {
itemPanel.setForeground(list.getForeground());
itemPanel.setBackground(list.getBackground());
}
return itemPanel;
}
}
发现不会出现上面的现象了。但是我不大理解为什么会这样,按道理说,JVM每次getListCellRendererComponent()绘制完后,对它们的引用就会消失,内存也会被回收,为什么会出现上面的现象内,哪位大侠能够给解释一下,谢谢了
解决方案 »
- 合并List,有没有好的办法 ?很着急,
- 二维数组
- 谁能给个API测试的代码,最好复杂点,或者相关文档也好,java的 100分
- 怎样实现文本文件与二进制文件相互转换
- nio读写的问题:服务器发送两次消息,客户端读取时会获得两条消息的叠加
- java最好用的文本编辑器是什么呀,在那下载呀
- 求救~程序崩溃~找不到问题所在
- 有没有好一点的java网站,象VC++中的www.codeproject.com,www.vckbase.com?
- 简单问题:我在jbuilder中用 import ConsoleReader.*的时候,提示我找不到目录???
- 关于socket通信 平台端向 多个server 发信息 多线程
- 正则表达式中&&为什么使用不起来?
- SQL安装无反应,怪了
我的理解是,对ListCellRender是不是根本就不回收。
也就是说
1.MainFrame中Combox初始化时,会调用getListCellRenderer()获取combox item的render进行绘制(最典型的就是renderer是JLabel的一个子类),
2.当用户选择combox出现下拉框时,也会调用此方法进行绘制
3.当combox失去焦点时,绘制完成的JLabel只是隐藏(或者被其他的component所覆盖),而不是被dispose,所以不会被回收,否则根本无法解释上面的代码会出现OutOfMemory Error.还望GUI高手给解释解释啊,谢谢了