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 server获取所有数据,并从远程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 上进行绘制。如果我重新启动程序,新公寓将被绘制在列表中,一切正常,直到我再次上传新公寓。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)