Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • Need help with an NPC java stream


    Cardozz

    Recommended Posts

    Posted

    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):

    1. stream Strings with a mapper instead of NPCs - worked.
    2. stream Integers with a mapper instead of NPCs - worked.
    3. 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??

    Posted

    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);
    
    Posted

     

    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

    Posted

    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?

    Posted

    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"

     

    6e8fe34b3504adb82b0a3f2208bac6d3.png

     

    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 :P

    Posted

    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"

     

    6e8fe34b3504adb82b0a3f2208bac6d3.png

     

    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 :P

    I mean...the real fix is to do a model.clear(); before you call populate function...

    Posted

    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 :P

    Posted

    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();
        }
    
    Posted
    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.

    Posted

    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?

    Archived

    This topic is now archived and is closed to further replies.

    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.