Cardozz 46 Posted July 21, 2016 I want to add a stream to my JList model so that a player can pick an NPC from the GUI, something like FiteLite by Raptor. I only want to add NPCs to the list by the following code: DefaultListModel<NPC> model = (DefaultListModel<NPC>) npcList.getModel(); context.getClient().getNPCs().stream() .filter(npc -> npc != null) .filter(npc -> !npc.isInCombat() .filter(npc -> npc.canAttack()) .filter(npc -> npc.hasAction("Attack")) .filter(npc -> context.getMap().canReach(npc)) .filter(npc -> !model.contains(npc)) //NOTE 1 .forEach(model::addElement); The problem, hovever, is that the stream doesn't always seem to recognize that the NPC is already added to the model, so it duplicates the NPC in the model when it goes off screen (null) to visible (!= null). It looks like the line with //NOTE 1 doesn't work properly. Like it doesn't seem to recognize that the model already has the npc in it. So i have done the following (thanks to Raptor): stream Strings with a mapper instead of NPCs - worked. stream Integers with a mapper instead of NPCs - worked. stream NPCs without a mapper instead of Strings and Integers - failed. I think that the mapper makes a difference, but you can't put npcs in a mapper and then check if these are in the model. Side note: the above code is without the mapper. This is when it looks like when i use the mapper: context.getClient().getNPCs().stream() .filter(npc -> npc != null) .filter(npc -> !npc.isInCombat() .filter(npc -> npc.canAttack()) .filter(npc -> npc.hasAction("Attack")) .filter(npc -> context.getMap().canReach(npc)) .map(NPC::getName).filter(name -> name != null && !name.equals("null")).distinct() .filter(npc -> !model.contains(npc)) .forEach(model::addElement); Any suggestions??
Calculus 30 Posted July 21, 2016 Try: private DefaultListModel<NPC> model; //Global variable //This populates the list getNpcs().all(npc -> npc != null && !npc.isInCombat() && npc.canAttack() && npc.hasAction("Attack") && getMap().canReach(npc)).stream().filter(npc1 -> npc1 != null).forEachOrdered(npc1 -> model.addElement(npc1)); //do a check to add to GUI if(model != null && model.size() > 0) yourModel.setModel(model);
Cardozz 46 Author Posted July 21, 2016 Try: private DefaultListModel<NPC> model; //Global variable //This populates the list getNpcs().all(npc -> npc != null && !npc.isInCombat() && npc.canAttack() && npc.hasAction("Attack") && getMap().canReach(npc)).stream().filter(npc1 -> npc1 != null).forEachOrdered(npc1 -> model.addElement(npc1)); //do a check to add to GUI if(model != null && model.size() > 0) yourModel.setModel(model); Unfortunately this doesn't work either. I added a !model.contains(npc1) check to it, but still same result Note that i am updating the list every 2 seconds or so without button presses
Calculus 30 Posted July 21, 2016 Unfortunately this doesn't work either. I added a !model.contains(npc1) check to it, but still same result Note that i am updating the list every 2 seconds or so without button presses Could you post your entire code? I'd love to fix this... Edit: You shouldn't have to check if it contains it or not...unless you're trying to have a single instance of the name? I.e. Without .contains: Goblin (lvl 3) Goblin (lvl 5) Goblin (lvl 2) Goblin (lvl 6) Goblin (lvl 3) With .contains: Goblin Which do you want?
Cardozz 46 Author Posted July 21, 2016 Could you post your entire code? I'd love to fix this... Edit: You shouldn't have to check if it contains it or not...unless you're trying to have a single instance of the name? I.e. Without .contains: Goblin (lvl 3) Goblin (lvl 5) Goblin (lvl 2) Goblin (lvl 6) Goblin (lvl 3) With .contains: Goblin Which do you want? Like i said: since it updates each 2 seconds, it will keep adding the monster if it filters through the stream. This happens when i dont use "contains" it keeps adding the monster because the npc keeps passing the filters. What i can do is just make a refresh button, but by doing this i will avoid this issue.. Something programmers don't do
Calculus 30 Posted July 21, 2016 Like i said: since it updates each 2 seconds, it will keep adding the monster if it filters through the stream. This happens when i dont use "contains" it keeps adding the monster because the npc keeps passing the filters. What i can do is just make a refresh button, but by doing this i will avoid this issue.. Something programmers don't do I mean...the real fix is to do a model.clear(); before you call populate function...
Cardozz 46 Author Posted July 21, 2016 I mean...the real fix is to do a model.clear(); before you call populate function... Yes, but then it won't save the selected npcs
Calculus 30 Posted July 21, 2016 private JList<NPC> npcjList; private DefaultListModel<NPC> model; private void populateNPCList(){ if(!model.isEmpty()) model.clear(); getNpcs().all(npc -> npc != null && !npc.isInCombat() && npc.canAttack() && npc.hasAction("Attack") && getMap().canReach(npc)).stream().filter(npc1 -> npc1 != null).forEachOrdered(npc1 -> model.addElement(npc1)); npcjList.setModel(model); } private java.util.List<NPC> getSelectedNPCs(){ return npcjList.getSelectedValuesList(); }
Cardozz 46 Author Posted July 21, 2016 private JList<NPC> npcjList; private DefaultListModel<NPC> model; private void populateNPCList(){ if(!model.isEmpty()) model.clear(); getNpcs().all(npc -> npc != null && !npc.isInCombat() && npc.canAttack() && npc.hasAction("Attack") && getMap().canReach(npc)).stream().filter(npc1 -> npc1 != null).forEachOrdered(npc1 -> model.addElement(npc1)); npcjList.setModel(model); } private java.util.List<NPC> getSelectedNPCs(){ return npcjList.getSelectedValuesList(); } I get it, but it will still remove the selected npcs first and then replace them after, meaning it will unselect your selection every loop.
Calculus 30 Posted July 21, 2016 I get it, but it will still remove the selected npcs first and then replace them after, meaning it will unselect your selection every loop. Rightttttt..........that's what you wanted though? You're re-initializing it every 2 seconds lmfao?
Recommended Posts
Archived
This topic is now archived and is closed to further replies.