NotifyDataSetChanged isn't updating arrayList when called the second time - java

Why is my question getting negative marks? i do not understand. Please help.
I have 5 lists displaying in the adapter one after another. I have to delete 2 rows when user clicks on a button in the activity. (Remove two options from the list every time the button is clicked) Each list gets the button click only once.
On click of button, NotifyDataSetChanged method does not update the list in the adapter.
For now it is happening for list 1, when 2nd list comes in, the button is clicked, 2 items from arraylist are deleted but notifyDataSetChanged does not update the list in the adapter.
In Activity :
row_number = count that i get from implementing the interface mentioned in adapter
private void removeTwoFunctionality() {
button_removeTwo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (row_number == 1) {
TextArray1.remove(0);
TextArray1.remove(1);
adapter.notifyDataSetChanged();
adapter.RemoveTwoButtonClicked();
}
if (row_number == 2) {
TextArray2.remove(0);
TextArray2.remove(1);
adapter.notifyDataSetChanged();
adapter.RemoveTwoButtonClicked();
}
if (row_number == 3) {
TextArray3.remove(0);
TextArray3.remove(1);
adapter.notifyDataSetChanged();
adapter.RemoveTwoButtonClicked();
}
if (row_number == 4) {
TextArray4.remove(0);
TextArray4.remove(1);
adapter.notifyDataSetChanged();
adapter.RemoveTwoButtonClicked();
}
if (row_number == 5) {
TextArray5.remove(0);
TextArray5.remove(1);
adapter.notifyDataSetChanged();
adapter.RemoveTwoButtonClicked();
}
}
});
}
In ADAPTER onBindViewHolder:
All the conditions are satisfied when next list arrives
// list 1
if (!TextArray1.isEmpty()) {
count = 1;
holder.name.setText(TextArray1.get(position).getTitle());
}
// list 2
if (TextArray1.isEmpty() && TextArray2.size() > 0) {
count = 2;
holder.name.setText(TextArray2.get(position).getTitle());
}
// list 3
if (TextArray2.isEmpty() && TextArray3.size() > 0) {
count = 3;
holder.name.setText(TextArray3.get(position).getTitle());
}
// list 4
if (TextArray3.isEmpty() && TextArray4.size() > 0) {
count = 4;
holder.name.setText(TextArray4.get(position).getTitle());
}
// list 5
if (TextArray4.isEmpty() && TextArray5.size() > 0) {
count = 5;
holder.name.setText(TextArray5.get(position).getTitle());
}
// interface to know the count in the activity
if (mOnAnswerListener != null) {
mOnAnswerListener.getRowNumber(count);
}

Try like this
TextArray5.remove(0);
TextArray5.remove(1);
adapter.RemoveTwoButtonClicked();
adapter.notifyDataSetChanged();

You should put notifyDataSetChanged after deleting the items :
TextArray5.remove(0);
TextArray5.remove(1);
adapter.RemoveTwoButtonClicked();
adapter.notifyDataSetChanged();

Related

Removing a material from an Itemstack out of players inventory

I am working on a plugin that allows players to fly at the cost of a item.
I have this code that works but only if the item is in the first slot of the players inventory (Hotbar) and no where else.
To enable fly I have a command class that checks the players inventory for redstone and if they have it, They are added to an arrayList based on their UUID. Inside of my onEnable I have a TaskTimer that runs continually and checks for players in the arrayList.
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
for (Player player : Bukkit.getOnlinePlayers()) {
if (Fly.flyingPlayers.contains(player.getUniqueId())) {
for (int i = 0; i < player.getInventory().getSize(); i++) {
ItemStack item = player.getInventory().getItem(i);
if (item !=null && item.getType().equals(Material.REDSTONE)) {
int amount = item.getAmount() -1;
item.setAmount(amount);
player.getInventory().setItem(i, amount > 0 ? item : null);
player.updateInventory();
break;
} else {
Fly.flyingPlayers.remove(player.getUniqueId());
player.setAllowFlight(false);
player.setFlying(false);
player.sendMessage(chatColor("" + this.getConfig().getString("Prefix") + "&4You are out of fuel"));
break;
}
}
}
}
}, 20L, 20L);
The issue comes from the if. If it's redstone, it will remove the item, else it will instantly think that it's finished instead of going to next slots.
You should do something like that:
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
for (Player player : Bukkit.getOnlinePlayers()) {
if (Fly.flyingPlayers.contains(player.getUniqueId())) {
boolean hasEdited = false;
for (int i = 0; i < player.getInventory().getSize(); i++) {
ItemStack item = player.getInventory().getItem(i);
if (item != null && item.getType().equals(Material.REDSTONE)) {
int amount = item.getAmount() -1;
item.setAmount(amount);
player.getInventory().setItem(i, amount > 0 ? item : null);
player.updateInventory();
hasEdited = true; // save that it have been edited
break; // break the for loop
}
}
if(hasEdited) // edited in for loop
continue; // go to next player
Fly.flyingPlayers.remove(player.getUniqueId());
player.setAllowFlight(false);
player.setFlying(false);
player.sendMessage(chatColor(this.getConfig().getString("Prefix") + "&4You are out of fuel"));
}
}
}, 20L, 20L);

Adding an object to a sorted array into the correct spot

So I have this project and im writing the add method for my catalog class and this add method needs to add an item to a sorted array into the right place using insertion sort, unless the array has nothing in it in that case i just want to add it in normally. this whole project must use an array I cannot use an arraylist or anything else.
The problem I am having here is that the way my program currently is, its only adding one object to my array and each time i try to add a new one during run tine it jst replaces the item already in there. I know that my problem is something in the body of my while loop and the way i initialize my position variable.
here is the method im having trouble with.
public void addItem(Item theItem)
{
int position = size;
if(size != 0){
while (position > 0 && theItem.compareTo(items[position - 1]) < 0){
items[position] = items[position - 1];
position--;
}
items[position] = theItem;
}
else{
items[size] = theItem;
size++;
}
here is my compareTo method
public int compareTo(Item other){
if(this.getItemType().equals(other.getItemType())){
return this.itemnum - other.itemnum;
}
//item types are not equal
else
return this.getItemType().compareTo(other.getItemType());
//try writing code to compare by price as well
}
The most likely problem in your code is this line:
items[position-1] = items[position];
This will copy an item in you array from the current position to the position to the left of it.
When you insert a new item you want to copy items from the left to the current position to make room for the new item to the left.
Change it to
items[position] = items[position-1];
A size++ is also missing after the while block, inside the first if block.
I realized this when adding a second call to addItem in my test code below.
You could also put a single size++ statement outside of the if statement.
A Complete, Minimal, Reproducible Example that I used trying to fix it. I have used Integer instead of Item to avoid having to add more classes.
public class Main {
private int size = 0;
private Integer[] items = new Integer[20];
public static void main(String... args) {
new Main().execute(); // Moving us into a non-static context
}
public void execute() {
System.arraycopy(new Integer[] {1,2,3,4,6,7,8,9}, 0, items, 0, 8);
size = 8;
// items = [1,2,3,4,6,7,8,9,null,null,...]
addItem(5);
addItem(5); // test adding a second item
// items = [1,2,3,4,5,6,7,8,9,null,null,...]
for (Integer i : items) {
System.out.println(i);
}
}
public void addItem(Integer item) {
int position = size;
if (size != 0) {
while (position > 0 && item.compareTo(items[position - 1]) < 0) {
// items[position-1] = items[position]; // Result [1,2,3,4,5,null,null,...]
items[position] = items[position-1]; // Result [1,2,3,4,5,6,7,8,9,null,null,...]
position--;
}
items[position] = item;
size++; // this line was missing as well
} else {
items[size] = item;
size++;
}
// or a single size++; here, removing the other two
}
}
The ugly solution by making new array
public int[] addItem(int item, int[] items){
int[] tempArr = new int[items.length + 1];
boolean hasAlready = false;
for(int i = 0 ; i < items.length; i++){
if(hasAlready)tempArr[i + 1] = items[i];
else if(item < items[i]){
tempArr[i] = item;
tempArr[i + 1] = items[i];
hasAlready = true;
}else {
tempArr[i] = items[i];
}
}
//items = tempArr; if items is global variable
return tempArr;
}
One can use existing utility functions, Arrays.binarySearch, and System.arraycopy. Your loop was 1 off.
public void addItem(Item theItem) {
Comparator<Item> comparator = Comparator.comparing(Item::getItemType)
.thenComparingInt(it -> it.itemnum);
int position = Arrays.binarySearch(items, 0, size, theItem, comparator);
// If position >= 0 the item was found (maybe no need to insert?)
if (position < 0) {
position = ~position; // Insert position of not found item
}
System.arraycopy(items, position, items, position + 1, size - position);
items[position] = theItem;
size++;
}
Binary search results in the non-negative index when found, or the negative ~index when not found. Here binary search is done on a subarray from 0 upto size (excluded).
Same as Roger Gustavsson
public class Main {
private int size = 0;
private Integer[] items = new Integer[20];
public static void main(String... args) {
new Main().execute(); // Moving us into a non-static context
}
public void execute() {
System.arraycopy(new Integer[] {1,2,3,4,6,7,8,9}, 0, items, 0, 8);
size = 8;
// items = [1,2,3,4,6,7,8,9,null,null,...]
addItem(5);
// items = [1,2,3,4,5,6,7,8,9,null,null,...]
for (Integer i : items) {
System.out.println(i);
}
}
public void addItem(Integer item) {
if (size == 0) {
items[size] = item;
size++;
return;
}
int position = size;
while (position > 0 && item.compareTo(items[position - 1]) < 0) {
items[position] = items[position - 1];
position--;
}
items[position] = item;
size++;
}
}
on what you are trying to achieve, i think next solution will be starting point from where you can build your own solution depending your specific needs. i have Changed your main method a little bit, and i do not know if your classes implements comparable /Comparator or not.
public void addItem(Item theItem) {
int position = position(items, theItem); // position is a method that finds best position for inseriton
if (items[position] == null){ // if items at best position is null then add new element there
items[position] = theItem;
} else{
items[size] = theItem; // if not add element at last position
swapUp(size); // and swap them up to perfect position.
}
size++;
}
method that find best position looks like this.
private static int position(Item[] items, Item newItem) {
if (isEmpty(items))
return 0;
int pos=0;
int target=items.length-1;
while(pos < target){
int m = pos+(target-pos)/2;
if (items[m] !=null){
if(newItem.getNumber()>items[m].getNumber()){ // comparing depending on item number
pos=m+1;
}else{
target=m;
}
}else{
target = m;
}
}
return pos;
}
as you can see method is looking for position depending on item number, you can change this with your type, or do both type and number comparison. Swaping up is handled by thus 2 method.
private void swapUp(int lastPosition){
if (lastPosition == -1){
return;
}
Item lastItem = items[lastPosition];
Item p = items[lastPosition-1];
if (lastItem.getNumber() < p.getNumber())
replace(lastPosition, lastPosition-1);
else
lastPosition = 0;
swapUp(lastPosition-1);
}
private void replace(int from, int to){
Item temporary = items[from];
items[from] = items[to];
items[to] = temporary;
}
and again i'm doing comparison of numbers you can implement any kind of comparison you want. i saw your previous question and modeled your classes
Music{number=1111, name='White and Nerdy', price=2.5, pro='"Weird Al" Yankovic'}
Music{number=2222, name='Amish Paradise', price=2.22, pro='"Weird Al" Yankovic'}
Music{number=3333, name='The Saga Begins', price=2.0, pro='"Weird Al" Yankovic'}
Movie{number=4444, name='UHF', price=9.99, pro='"Weird Al" Yankovic'}
Movie{number=5555, name='The Dark Crystal', price=8.99, pro='"Jim Henson'}
Movie{number=6666, name='Die Hard', price=13.99, pro='Bruce Willis'}
Movie{number=6969, name='The Adventures of Mr. Winky', price=9.99, pro='Richard Dickinson'}
Book{number=7777, name='When I Grow Up', price=7.98, pro='"Weird Al" Yankovic'}
Book{number=8888, name='The Chronicles of Pern: First Fall', price=5.99, pro='"Anne McCaffrey'}
Book{number=9999, name='Get gud you scrub', price=2.5, pro='Steve "Troll" Rathier'}
as you can see they are in sorted order.

TableRowSorter shows different result everytime I clicked searchButton

For my code, I had a really weird bug.
Everytime I press the Search Button, the result always different.
This is my dummy database.
I have 4 columns and 3 rows in the table :
001 Viagra 1 APL
002 Diane 2 SBF
003 Santibi 3 BSP
The first time I pressed the Search Button, the data inside table didn't change at all.
This is the screenshot of my program.
This is what happened if I pressed the Search Button the second time (the result is correct)
The third time I pressed the button, it shows an incorrect result
If I pressed the button continuously, the result keep changing back and fort from correct to incorrect one.
This is my code :`
public void searchPerformed() {
if (tSearch.getText().toString() == sch) { return; }
sch = tSearch.getText().toString();
int iColumn = cbSearch.getSelectedIndex();
TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
tbl.setRowSorter(sorter);
if (tSearch.getText().length() > 0) {
sorter.setRowFilter(RowFilter.regexFilter("(?i)" + tSearch.getText(), iColumn));
} else {
sorter.setRowFilter(null);
}
if (tbl.getRowCount() != 0) { tbl.setRowSelectionInterval(0, 0); }
else { clearText(); }
}
private void tSearchKeyPressed(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode() != KeyEvent.VK_ENTER) { return; }
searchPerformed();
}
private void tSearchKeyPressed(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode() != KeyEvent.VK_ENTER) { return; }
searchPerformed();
}

How to set click limit of clicking a button? click limit is equal to score over 5

How can I set a limit of clicking a button? The number of click is equal to score % 5.Example score is equal to 15 the number of click limit is equal to 3 how can I do that? my codes is not working
int score = 0;
int help = score % 5;
if (score == help) {
helpbtn.setEnabled(false);
} else {
helpbtn.setEnabled(true);
}
I put it inside of
public void onClick(View v) { }
If in the example limit is 3, then :
if(help>0)
{
//logic;
help--;
}
you can add it in else block.
I think I understand what you need now. I've made some assumptions. I added a separate button to submit answers and I added a boolean that is always true for now. I did manage to use modulo in this version though. Hope this helps.
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private int score = 0;
private int help = 0;
private boolean answerCorrect = true; // dummy set always true for now
private Button answerButton = null;
private Button hlpbtn = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
answerButton = (Button)findViewById(R.id.button_answer);
answerButton.setOnClickListener(this);
hlpbtn = (Button)findViewById(R.id.button_help);
hlpbtn.setOnClickListener(this);
hlpbtn.setEnabled(false);
}
#Override
public void onClick(View view) {
if(view.getId() == R.id.button_answer) {
if(answerCorrect) {
if((++score % 5) == 0) {
++help;
}
if((help > 0) && !hlpbtn.isEnabled()) {
hlpbtn.setEnabled(true);
}
}
Log.d("Quiz", "score = " + score + ", help = " + help);
} else if(view.getId() == R.id.button_help) {
if(--help <= 0) {
hlpbtn.setEnabled(false);
Log.d("Quiz", "help button disabled");
}
Log.d("Quiz", "help pressed, " + help + " remaining");
}
}
}
It sounds like you want 15 / 5 instead of 15 % 5.
15 / 5 == 3, whereas 15 % 5 == 0.
15/5 =3. Try this, this will help you to click a button 3 times.
%it gives remainder. Ie --->15%5=0

Creating a day schedule

I just need some help with one part of my code. I have 3 classes, Activity, DaySchedule, and DayScheduleFrontEnd. In the DaySchedule Class a have a method called addActivity:
public void AddActivity(Activity aActivity)
{
//Check if activity array is full
if(activities[activities.length-1] != null)
{
System.out.println("The activities database is full");
return;
}
//Find the first empty space
for(int i=0;i<activities.length;i++)
{
if(activities[i] == null)
{
activities[i] = aActivity;
break;
}
}
this.SortActivitiesByTime();
}
What I need help on is that an activity cannot conflict with another one. An activity conflicts if the start and the end of one activity cannot fall at the same time as another. If this were to occur the user should be notified and the activity is not added. Also this method should finally sort the activities based on their starting time. So for example if I had Activity: BreakFast StartHour: 8 EndHour: 9 and then Activity: Breakfast part 2 StartHour: 8 EndHour: 10 it would print out saying that there is a conflict.
Accessors from Activity Class
getStartHour()
getEndHour()
First of all create a function in Activity class called hasConflict(Activity other). In the function check if there is a time conflict. I do not completely agree with how you are keeping time in your activity. You should keep two Date called start and end and use the getTime() to see if there is a conflict between two activities. It should be a simple if statement.
Second, change your activities array to LinkedList<Activity>. You keep MAX_SIZE of your list and check that before saying that the database is full
Third use Collections.sort() to sort your activities. There are two ways to call that function.
Implement Comparable for your Activity class and compare the provided activity with this activity in the function
Implement Comparator and provide an instance of that to this function
Once you have all of the above, you can write your functions to
First check if there is space in your database by checking list.size() with MAX_SIZE
Iterate through the list and see if the new activity has any conflict with any existing one
If all of above is ok, add the activity to list and sort whenever you want.
There are better ways than sorting as in adding the activity to correct index the first time while you are iterating the activities to check for conflict but this will do for now.
I believe you are not doing it the best possible way. You insert an element at the end of the array and then sort the whole thing. However, you start with an empty array and then activities are added. You should find the place where you can insert the element and shift other elements to the right.
public void AddActivity(Activity aActivity)
{
//Check if activity array is full
if(activities[activities.length-1] != null)
{
System.out.println("The activities database is full");
return;
}
//Find the desired location and the first empty space
int desiredLocation = -1;
int firstEmptySpace = -1
for(int i=0;(i<activities.length) && (firstEmptySpace == -1);i++)
{
if ((desiredLocation == -1) && (aActivity.getEndHour() > activities[i].getStartHour()))
{
if (aActivity.getStartHour() < activities[i].getEndHour())
{
//Intersection :(
return;
}
else
{
desiredLocation = i;
}
}
if(activities[i] == null)
{
firstEmptySpace = i;
}
}
//shift things to the right
for (int i = firstEmptySpace; i > desiredLocation; i--)
{
activities[i] = activities[i - 1];
}
//Override previous value at desired location
activities[desiredLocation] = aActivity;
}
Below, is a version using collections, while keeping the total amount and order and uniqueness of elements by using a TreeSet. I didn't include the get/set methods, but it should be straightforward.
import java.util.Comparator;
import java.util.Objects;
import java.util.TreeSet;
public class Activity {
public long startHour;
public long endHour;
public static final int MAX_SIZE = 10;
public static TreeSet<Activity> activities = new TreeSet<>(new Comparator<Activity>() {
#Override
public int compare(Activity o1, Activity o2) {
return Long.compare(o1.startHour, o2.startHour);
}
});
public boolean intersect(Activity activity) {
return (activity.startHour >= this.startHour && activity.startHour < this.endHour)
|| (this.startHour >= activity.startHour && this.startHour < activity.endHour);
}
#Override
public String toString() {
return "start: " + startHour + ", end: " + endHour;
}
#Override
public int hashCode(){
return Objects.hash(startHour, endHour);
}
#Override
public boolean equals(Object object) {
if (this == object) return true;
Activity other = (Activity) object;
return (startHour == other.startHour) && (endHour == other.endHour);
}
public static void addActivity(Activity aActivity)
{
if (activities.size() >= MAX_SIZE) {
System.out.println("The activities database is full");
return;
}
for (Activity a : activities) {
if (a.intersect(aActivity)) {
System.out.println(String.format("Activity %s intersect with %s", a, aActivity));
return;
}
}
activities.add(aActivity);
}
public static void main(String[] args) {
Activity a1 = new Activity();
a1.startHour = 0;
a1.endHour = 5;
Activity b1 = new Activity();
b1.startHour = 3;
b1.endHour = 7;
Activity b2 = new Activity();
b2.startHour = 5;
b2.endHour = 9;
Activity b3 = new Activity();
b3.startHour = 1;
b3.endHour = 2;
addActivity(a1);
addActivity(b1);
addActivity(b1);
addActivity(b2);
addActivity(b3);
System.out.println(activities);
}
}

Categories