java - Java Swing自定义JList cellRenderer在添加新元素后未绘制所有元素
问题描述
所以这是我作为新手的第一个更大的项目。这个项目主要是一个 Swing GUI 应用程序,它基本上是一个公寓猎人应用程序。实际上,这是一个非常大的程序(至少对我来说),而且代码非常混乱,但我会尽力包含所有必要的内容。所以在程序中,其中一个 JPanel 包含一个 Jlist,其中包含所有可用的公寓,并且有一个自定义的 cellRenderer 类。看起来像这样(我将在代码片段之后详细说明所有内容):
class PanelRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(
JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus);
Pair pair = sqldata.getInfo((String)value);
if(MainController.data_storage!=null){
ImageIcon final_img = MainController.data_storage.get((String)value).get(0); //(String)value is From nameList array
label.setIcon(final_img);
}
ArrayList<String> tmp = sqldata.apartmentDetails(pair.getValue()+"");
if(tmp.size()>0){
ids.add(tmp.get(tmp.size()-1));
}
label.setText("<html>Title: "+pair.getValue()+" <br/> Price: "+pair.getKey()+" <br/> Owner: "+value+"<br/> <br/>"
+ " Room type: "+tmp.get(0)+" <br/> Room num: "+tmp.get(1)+" <br/> "
+ " Balcony: "+(tmp.get(2).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Pet: "+(tmp.get(3).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Yard: "+(tmp.get(4).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Smoke: "+(tmp.get(5).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Quiet: "+(tmp.get(6).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+" "
+ " Deposit: "+(tmp.get(7).equals("true") ? "<font color='green'>✓</font>" : "<font color='red'>×</font>")+"</html>");
label.setHorizontalTextPosition(JLabel.RIGHT);
value = tmp.get(tmp.size()-1);
return label;
}
}
所以这一行:Pair pair = sqldata.getInfo((String)value);
返回价格和公寓的标题。
此行:ImageIcon final_img = MainController.data_storage.get((String)value).get(0);
返回与公寓所有者姓名关联的图像。
下一行:ArrayList<String> tmp = sqldata.apartmentDetails(pair.getValue()+"");
返回公寓的其余部分。例如:城市、房间类型、宠物等。所以一个列表项有一张图片,还有一些文字。
我的应用程序有一个搜索按钮,按下时会从 sql 服务器获取所有数据,并从远程 FTP 服务器下载相应的数据。之后,Jlist 会显示结果。还有过滤器选项,如阳台、宠物、价格和城市。到目前为止,这些工作正常。上传新公寓后出现问题。如果我在上传新公寓后单击搜索按钮,所有内容都会正确返回(在内部,如列表),除了列表中的所有彩绘元素。因为什么都没有画。所以在插入(上传)之后,数据被插入到 SQL 表中,图像上传到 FTP 服务器上。这部分很好。此外,当我刷新将元素提供给 JList 的 arrayList 时,它会告诉我新公寓在其中(以及旧公寓)。但是 JList 上没有显示任何内容,它完全是空白的。此代码正在上传:
if(validFile()){
if(!uploadMenuValidate()){
if(!img_container.isEmpty()){
for(File f : img_container){
try {
ftp.putFileToPath(f, FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+f.getName());
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
sqldata.insert(SQLData.QUERY_ADD_APARTMENT, SQLData.APP_USERNAME,uploadmenu.getPriceField().getText(),uploadmenu.getCityField().getText(),uploadmenu.getRoomTypeSelector().getSelectedItem().toString(),
uploadmenu.getRoomNum().getText(),uploadmenu.getBalconyCheck().isSelected()+"",uploadmenu.getPetCheck().isSelected()+"",uploadmenu.getYardCheck().isSelected()+"",uploadmenu.getSmokeCheck().isSelected()+"",
uploadmenu.getFreqCheck().isSelected()+"",uploadmenu.getDepositCheck().isSelected()+"",img_container.size()>0 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(0).getName() : "",
img_container.size()>1 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(1).getName() : "",img_container.size()>2 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(2).getName() : "",
img_container.size()>3 ? FtpClient.DEST_DIR+SQLData.APP_USERNAME+"/"+img_container.get(3).getName() : "",uploadmenu.getDetailsBox().getText(),uploadmenu.getApTitle().getText(),mainc.getUniqueId());
showInfoPanel("misc.INFO_UPLOAD_SUCCESS");
data_storage = mainc.getApartments(sqldata.getApartments());
}
}
}
这里:data_storage = mainc.getApartments(sqldata.getApartments());
内部 ArrayList 被刷新,它基本上包含了 JList 的元素。
一些可能很重要的代码:
mainJListPanel = new JList(nameList);
public String[] nameList = makeList();
public String[] makeList(){
int n = sqldata.getApartments().size();
HashMap<String,List<String>> kt = sqldata.getApartments();
String[] tmp =new String[n];
ids = new ArrayList<>();
int i = 0;
for (String x : kt.keySet()){
tmp[i++] = x; //Getting the owner names
}
return tmp;
}
public static String[] searchList(){
int n = MainController.data_storage.size();
String[] tmp = new String[n];
int i = 0;
for (String x : MainController.data_storage.keySet()){
tmp[i++] = x;
}
return tmp;
}
搜索按钮执行此操作:
data_storage = getApartments(sqldata.getSearchedApartments(mainmenu.getMenuMinPrice().getText()+"",mainmenu.getMenuMaxPrice().getText(),mainmenu.getMenuCity().getText(),
String.valueOf((int)mainmenu.getMenuRoomNum().getValue()),mainmenu.getMenuRoomType().getSelectedItem()+"",mainmenu.getMenuBalcony().isSelected()+"",mainmenu.getMenuYard().isSelected()+"",mainmenu.getMenuPet().isSelected()+"",
mainmenu.getMenuSmoke().isSelected()+"",mainmenu.getMenuFreq().isSelected()+"",mainmenu.getMenuDeposit().isSelected()+"", mainmenu.getMenuMiscText().getText()));
//Getting everything from the filter, and //converting it into an SQL query --> This is working, the sql command is OK.
mainmenu.setNameList(mainmenu.searchList());
mainmenu.getMenuMainPanel().revalidate();
mainmenu.getMenuMainPanel().repaint();
//mainmenu is the instance of the JPanel, which contains the Jlist
奇怪的是,如果我检查一个过滤器选项,比如阳台,JList 会绘制结果。甚至新公寓也在上传的结果中。但是当我删除所有过滤器时,(所以基本上我希望每间公寓都回来),列表不会画任何东西。所以只有当我处于“上传后”状态时才会出现错误,并且我希望每个公寓都被绘制在 Jlist 上。如果我重新启动程序,新公寓将被绘制在列表中,并且一切正常,直到我再次上传新公寓。
解决方案
推荐阅读
- docker - 在 Openshift 中从 Dockerhub Registry 更新 ImageStream
- javascript - PHP根据客户端的电子邮件地址从dc.selectMenu中选择
- google-compute-engine - 需要更新哪些 Compute Engine 配额才能使用 50 个工作人员(IN_USE_ADDRESSES、CPUS、CPUS_ALL_REGIONS ..)运行 Dataflow?
- angular - NgRx Effect 中的返回类型问题
- python - 将 GeoPandas 数据框写入 SQL Server 时遇到问题
- javascript - 在命名空间中导入一个 JavaScript 模块,例如,对于 D3
- macos - 即使有 dylib 符号也无法读取
- c - 使用 if else 语句代替 while
- javascript - Tampermonkey 脚本中 getElementsByTagName 的异常行为
- c - 为什么 32 位编译器和 64 位编译器会对我的代码产生如此大的影响?