UI keeps Updating in Debug but without it nothing happens - java

I want to populate a table with data.
The following Code are two bits out of the controller, because I sadly don't know which part is important.
Each function is supposed to take an Observable List which was declared in the main phase and clear it out.
Then add new Entries according to the current status of the arrays and in the end use populate() to populate the table with it.
But this sometimes fails. The data is added into the arrays, but it isn't shown in the table.
Has anybody an idea what could be the reason for that?
public void showAll() {
//Clear existing data
Main.data = FXCollections.observableArrayList();
//add new data on base of the arrays
for (int i = 0; i < Main.array_anz.length; i++) {
if (Main.array_pla[i] != 0) {
Main.data.add(new Article(Main.array_bez[i], Main.array_pla[i], Main.array_gew[i], Main.array_pre[i], Main.array_anz[i], Main.array_kat[i]));
} else {
i++;
}
}
//Show the data in the table
populate();
}
private void populate() {
ArtikelbezeichnungTable.setCellValueFactory(new
PropertyValueFactory<Article, String>("artikelbezeichnung"));
LagernummerTable.setCellValueFactory(new PropertyValueFactory<Article,
Integer>("lagernummer"));
GewichtTable.setCellValueFactory(new PropertyValueFactory<Article,
Double>("gewicht"));
AnzahlTable.setCellValueFactory(new PropertyValueFactory<Article,
Integer>("anzahl"));
KategorieTable.setCellValueFactory(new PropertyValueFactory<Article,
String>("kategorie"));
StorageTable.setItems(Main.data);
}

Related

ArrayList updated inserting one row but Jtable still not refresh

I've to create a java swing app that allows the user to menage some Oracle tables.
I've implemented the JTable in this way:
public class TableModel extends AbstractTableModel{
.
.
.
public List <List <String> > result = null;
.
.
.
public void createTable(ResultSet r) throws SQLException {
rs = r;
numcols = getColumnCount();
result = new ArrayList();
while (rs.next()) {
List <String> row = new ArrayList<>(numcols);
for (int i=1; i<= numcols; i++)
row.add(rs.getString(i).replace("00:00:00.0", "")); //just managing stuffs .. nothing important. Don't care of this replace.
result.add(row);
}
fireTableStructureChanged();
}
public void addRow(){
List <String> row = new ArrayList<>();
for(int i=1;i<=getColumnCount();i++)
row.add("");
result.add(row);
fireTableStructureChanged();
}
public Object getValueAt(int row, int col) {
return result.get(row).get(col);
}
public int getColumnCount() {
if (rs == null) {
return 0;
}
try {
return rs.getMetaData().getColumnCount();
} catch (SQLException e) {
System.err.println("error in colcount");
return 0;
}
}
public int getRowCount() {
int totalRows = 0;
try {
rs.last();
totalRows = rs.getRow();
rs.beforeFirst();
} catch(Exception ex) {
return 0;
}
return totalRows ;
}
}
so, I store database data into the arraylist and then I print the table using the arraylist.
Now in the addRow() function I add to that arraylist an empty record (in my mind an empty record is a record composed of all null ("") strings).
Finally using the fireTableStructureChanged() method I expect the table to refresh itself.. but this will never occur and I don't understand why.
I've already checked that the new row is successfully loaded into the arraylist:
I got all the data stored in the table of the Database into the arraylist and the new row is successfully loaded in the arraylist.
so I swear the problem is about that fireTableStructureChanged() method.
Thanks :3
Try using fireTableRowsInserted(int firstRow, int lastRow) instead of fireTableStructureChanged()
Here's the javadoc for the structure changed ...
Notifies all listeners that the table's structure has changed. The number of columns in the table, and the names and types of the new columns may be different from the previous state. If the JTable receives this event and its autoCreateColumnsFromModel flag is set it discards any table columns that it had and reallocates default columns in the order they appear in the model. This is the same as calling setModel(TableModel) on the JTable.
So that one will only work if the columns types changed ...
If you are lazy go for this one: fireTableDataChanged()
I found the solution.
That's quite embarassing..
#tsolakp you helped me a lot!
Since before using ArrayList I was working on ResultSet directly, I forgot to update getrowcount.
So, since the inserting was only "client side" on the arraylist, the rows displayed were only "n" (where n was the number of rows on the database). So I would never displayed my new row since it was not loaded into the database.
That's all :)
Maybe working hard on coding, makes these errors invisible :X

Java ArrayList trying to check if object with this name exists

I'm having a bit of trouble in my head trying to solve this:
I'm working on a "rankList", an arrayList made of "Score". Score it's the object that has the following atributes: name,wins,loses,draws. My class Ranking has an ArrayList of Score objects. To create a new Score object I just use the name (and set the rest to 0 since it's new). However I'm trying to check if the player's name it's already in rankList I don't have to create new but sum a win or lose or draw.
I have been reading arround that I have to override equals then others say I have to override contains... It's getting a big mess in my head. My fastest solution would be to write an "for" that goes arround the arrayList and use the getName().equals("name"); however this is getting too messi in my code. I have checkPlayer (if the palyer is in the list):
public boolean checkPlayer(String playerName) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
return true;
}
}
return false;
}
then if I want to incrase the wins i have this :
public void incraseWins(String playerName) {
if (checkPlayer(playerName)) {
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
} else {
createPlayer(playerName);
//more for to get to the player i'm looking for...
for (int i = 0; i < this.rankList.size(); i++) {
if (this.rankList.get(i).getName().equals(playerName)) {
this.rankList.get(i).setWins(this.rankList.get(i).getWins() + 1);
break;
}
}
}
So i guess there is a better way to do this... :/
ArrayList is not the right data structure here. To check if an element exists in the array you are searching the entire arraylist. Which means it's O(N).
To keep an array list is sorted order and do a binary search on it would definitely be faster as suggested in the comments. But that wouldn't solve all your problems either because insert into the middle would be slow. Please see this Q&A: When to use LinkedList over ArrayList?
One suggestion is to use a Map. You would then be storing player name, player object pairs. This would give you very quick look ups. Worst case is O(log N) i believe.
It's also worth mentioning that you would probably need to make a permanent record of these scores eventually. If so an indexed RDBMS would give you much better performance and make your code a lot simpler.
Try using a hashtable with a key, it would be much more efficient!
e..Why not using map<>.
a binary search is good idea if you must use List,code like this
List<Method> a= new ArrayList<>();
//some method data add...
int index = Collections.binarySearch(a, m);
Method f = a.get(index);
and class method is impl of Comparable,then override compareTo() method
public class Method implements Comparable<Method>{
........
#Override
public int compareTo(Method o) {
return this.methodName.compareTo(o.getMethodName());
}
if you don't want use binsearch,CollectionUtils in commons can help you
CollectionUtils.find(a, new Predicate() {
#Override
public boolean evaluate(Object object) {
return ((Method)object).getMethodName().equals("aaa");
}
});
in fact CollectionUtils.find is also a 'for'
for (Iterator iter = collection.iterator(); iter.hasNext();) {
Object item = iter.next();
if (predicate.evaluate(item)) {
return item;
}
}

Clearing a dropdown counter in Java?

I need to clear all the fields in several arrays to re-load a new template to parse. I currently set up a function to clear all the relevant array lists and counts. Those are working fine except I am having a hard time clearing out obrDD inside my clearMicroArray() function.
Here is my current code (without logic to clear obrDD). How can I clear the dropdown information inside my function?
static void clearMicroArray() {
fullMicroArray.clear();
int returnSize = fullMicroArray.size();
System.out.println("size of full array" + returnSize);
obrCount = 0;
fileRowCount = 0;
// obr List
obrList.removeAll(obrList);
obxList.removeAll(obxList);
};
// Populating the OBR number in dropdown
public static void populateOBRDropdown(JComboBox<String> obrDD) {
for (int i = 0; i < fullMicroArray.size(); i++) {
if (fullMicroArray.get(i).substring(0, fullMicroArray.get(i).indexOf("|")).equals("OBR")) {
i++;
obrCount++;
obrDD.addItem("OBR " + obrCount);
}
}
}
obrDD is a JComboBox object that you pass into populateOBRDropdown. Your clearMicroArray method, however, also needs obrDD as an input in order for you to do anything with it. Once you pass a reference to the JComboBox, you can call removeAllItems or removeItem from clearMicroArray.

Copying Array from ArrayList Element

I'm building a Java based game in Swing, which is essentially a grid of Jbuttons
I have an Object called Cell, which is a custom JButton with additional parameters for storing objects. The game grid is represented by Cell[][]
I have an arraylist of type Cell[][] to allow me to store the state of the gamegrid after each move. If I want to undo the move, I need to copy the last element of the ArrayList to the game grid to allow it to be displayed on the UI.
My gamegrid is panelHolder and my arraylist is moveHolder.
So far I've tried Collections.copy(panelHolder, moveHolder.get(moveHolder.size())); which will not compile due to the "arguments not being applicable for the type Cell[][]"
I've also tried System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);, which throws and out of bounds exception. Initially I thought this was due to the moveHolder.size()-1, but even just as moveHolder.size() it has the same problem.
I've found numerous questions on StackOverflow and others that both show these two ways of doing it, but I can't seem to get it to work. Is there something more obvious I'm missing? Full class method below:
public class UndoClass implements MoveCommand{
public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();
public Cell[][] execute(Cell[][] panelHolder) {
if (moveHolder.size() > 0){
Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));
if (moveHolder.size() > 0){
moveHolder.remove(moveHolder.size());
}
}
System.out.println("Move Undone. Undos available:" + moveHolder.size());
return panelHolder;
}
public void addMove(Cell[][] panelHolder){
moveHolder.add(panelHolder);
}
public ArrayList<Cell[][]> getMoves(){
return moveHolder;
}
}
Cell Class
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
Just wanted to point our your execute(...) method accepts the Cell[][] both as a parameter and the return argument. That approach is going to force all of your commands to keep copying your input param arrays to the return statement array. Notice if you don't need to keep the two in sync and you just use the return arg, you don't have to worry about copying at all:
Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState; // Not updating the panelHolder array, just returning
But of course now the input parm and return are out of sync. Instead you might want to encapsulate that state into a single object to make your life easier. Something like this (note that the execute now returns a void):
public ArrayList<GameState> previousStates = new ArrayList<GameState>();
public void execute(GameState currentState) {
if (previousStates .size() > 0) {
GameState lastState = previousStates.get(previousStates.size()-1);
currentState.restoreFrom(lastState);
previousStates .remove(moveHolder.size()-1);
}
}
Good luck on the game!
if (moveHolder.size() > 0) {
for (int i = 0; i < panelHolder.length; i++) {
panelHolder[i] = moveHolder.get(moveHolder.size()-1)[i].clone();
}
moveHolder.remove(moveHolder.size()-1);
}
Try this. You need to make copies of each internal array when copying 2D arrays.
Try a Linked List
LinkedList<Cell[][]> ll = new LinkedList();
ll.removeLast();
panelHolder = ll.clone();

Having trouble understanding how to maintain state using classes

I'm new to using OOP, I typically just put all my code in a single class and use methods. But I want to maintain state information and think classes are the best fit but I'm having trouble wrapping my head around it.
Say I have a list of items and I want to stop when the total sum of all previous items in the list equals X(in this case 10 so it takes item 1 + 2, then 2+3.etc..until it hits the threshold 10), I can use a method to calculate it but it involves me doing the entire process all over again when all I really need to do is increment by the last item and then see if my data exceeds the threshold. Here's my code so far but I know its not good because although it works its really just using the class as an independent method and recalculating on every loop. My goal is to,using this structure, reduce loops if not necessary to check thresholds.
Any suggestions?
Code:
public class LearningClassesCounter {
public static void main(String[] args) {
int[] list = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] data_list = new int[list.length];
for (int current_location = 0; current_location<list.length;current_location++) {
//can only put commands in here. Nothing above.
Counter checker = new Counter(data_list);
System.out.println(checker.check_data(current_location));
for (int i =0; i<100; i++){
if (checker.check_data(current_location) == false) {
break;
}
data_list[current_location] = (list[current_location]+1); //this is just a random function, it could be any math function I just put it in here to show that some work is being done.
}
}
//its done now lets print the results
for (Integer item : data_list) {
System.out.println(item);
}
}
}
class Counter {
private int[] data_list;
private int total_so_far;
// create a new counter with the given parameters
public Counter(int[] data_list) {
this.data_list = data_list;
this.total_so_far = 0;
}
public boolean check_data(int current_location) {
// TODO Auto-generated method stub
int total_so_far = 0;
//System.out.println(total_so_far);
for (int item : data_list) {
total_so_far = item + total_so_far;
if (total_so_far >= 10) {
break;
}
}
if (total_so_far>=10) {
return false;
} else {
return true;
}
}
}
I don't need anyone to fix my code or anything(I want to do it myself, the code is just to give an idea of what I'm doing). I'm more interested in the flaw in my logic and maybe a way for me to better think about designing classes so I can apply them to my own situations better.
So the solution is that you do not update the data_list directly. Instead have a setter method in the Counter class that takes the index and value to update. It updates the value in the array and also updates a count value.
Something like this:
class Counter{
private final int[] list;
private count = 0;
private final maxCount = 10;
public Counter(int[] list){
this.list = list;
}
public boolean updateValueAndCheckPastMax(int index, int value){
list[index] = value;
count += value;
return count >= maxCount;
}
}
You are way over thinking this, and a counter class is not really necessary in this case.
I'm also interested as to why you'd be doing this line:
data_list[current_location] = (list[current_location]+1);
Do you want your data_list to be the same as list, but each value is incremented by 1?
If you are merely trying to return a sub-array of the values that are < 10, i would suggest just doing this in a for loop, and using an int as a counter.

Categories