I'm about to share abit interesting case here about the java programming and its variables.
First thing I wanted to say is that, we are in these situations:
We have many JLabels with its Naming conventions
(*jll_txtNormalCnn*).
The 'nn' literally means a coordinate of (x,y). TO be
precise, it is a digit of (0-9).
The screenshot of the many Variables used here.
In the screenshot taken; We may see there are 5 x 3 table.
And each column consist of each JLabel placed above it. So it is mimicing as a board with a text on it.
My very simple question is not about the Interface, instead; it is about the programming style. What if.... The variables are sooOOO many. Let say there are 100 Variables using that kind of naming conventions. And once we want to setText() to each of the variables, we want to simplify the coding- instead of typing it one by one.... we wanted to use for-looping to reach each of the Variable.... But, I realized it is impossible.
The code below will not work at all;
for (int x=00; x<101; x++){
(jll_txtNormalC+x).setText("Something");
}
Is there any way around to solve this matter?
I'm not sure whether this is a topic of Dynamic Variable or something, because I never heard about it in Java, except 'Generics', yes I've heard.
I don't think it's a generics problem. It's not about dynamic variables, either. It sounds to me like you're having problems because you've embedded information about the location of the label in a grid inside the variable name. That's a very bad idea, in my view.
Maybe a better idea is to encapsulate that information inside another object and let it maintain the grid of labels. That's far better than your variation on Hungarian notation.
Simply put: don't use separately named variables for this. Use a collection of some kind, whether it's an array (possibly a JLabel[][]), a map or whatever is appropriate.
1) if is your requirement(s) strict quadratic and there are JLabels or JTextFields (with its Swing nested/inherits methods and its derivates including pictures),
2) if you required periodical changes for Component's contents
3) if you want to avoiding memory leaks or GPU performace or freeze
4) if you want to simple and easy to get/set data or changes
then put that to the JTable, by defalut contains JLabel in the cell, by defalut contains JTextField on CellEdit (Mouse or Keyboard input)
1) then you can pretty to forgot about naming, possitionig and another ZOO, all three areas from MVC and JTable would be still consistent
2) you can access to data just from visible/filtered/sorted/removed/rendered TableView
3) you can access to all data from TableModel
4) plus all JTable's features that were added/cames from Java6
5) save lots of time for LayoutManager, possitioning on the screen, Listeners, access to the concrete Component
Normally, when working with grids or matrices you use 2d arrays.
Store your JLabels in a 2d array. You can iterate over them or access labels at (x, y) grid-coordinates using [x][y] notation which is easy to read.
JLabel[][] labelArray = new JLabel[numRows][numCols];
for(int i = 0 ; i < labelArray.length; i++) {
for(int j = 0; j < labelArray[i].length; j++) {
labelArray[i][j].setText("Something");
}
}
store the jlabels in an array (5x3 or 10x10).
You need to use some sort of UI container component (something like a grid), or maybe just an array.
OTOH idea: create an ArrayList or an array and populate it with Jlabels. Iterate through the collection and call setText for each one.
the prober answer is the several times mentioned 2d array.
but, if your labels have to remain single variables, you can also solve this with reflection:
for (int x=00; x<101; x++){
Field f = getClass().getDeclaredField("jll_txtNormalC" + x);
JLabel l = (JLabel)f.get(this);
l.setText("Something");
}
Related
I have a JPanel called panelCreatePuzzle with 100 JButton's.
I used
Component[] cells = panelCreatePuzzle.getComponents();
To get an array of all the buttons. Now I want to print the text of each button. I have no clue how to do this. I tried the following:
for (Component cell:cells){
System.out.println(cell.toString());
}
Which does print something containing the text:
javax.swing.JButton[,321,321,30x30(...),text=here is the text,defaultCapable=true]
I can of course extract it from this string, but is there a more direct way that just gives me the text without anything else?
There are better ways to achieve what you're trying to do, but...
for (Component cell:cells){
if (cell instanceof JButton) {
JButton btn = (JButton)cell;
String text = btn.getText();
}
}
Basically, you need to determine if the component is actually a JButton or not and if it is, you can then safely cast it and work with it.
This is limited and a little brute force. A better approach might be to supply a getter which return an array of the buttons which represent the cells (rather then looking at all the buttons, which might include things you don't want).
Probably the best solution though, is to use some kind of model, which represents the current state, which can then be used to displayed through the UI and manipulated in what ever form you want in a de-coupled manner.
This reaches into a large array of concepts, including "model-view-controller" and "observer pattern", concepts which you should take the time to investigate and learn
Hi everyone I am making a simple Libgdx game on Android that involves touching the screen and hitting things. However I have came across a slight problem. I have a small selection of weapons to choose from but I don't know what the best way is to actually draw/access the selected weapons. They are all inherited from a basic weapon class. Right now I have a normal hammer class and a fast hammer class which extends hammer.
The fast hammer has some special methods and swings faster. When I just instantiate the classes I want to test it works fine. However I want to do a check to see which hammer has been selected beforehand and then access it and draw it. I can't think of a very elegant way to do this other than a whole mass of if statements.
I originally tried giving a check variable an int. Then If int 1 then hammer = new normalhammer(); else if int 2 then hammer = new fasthammer(); but this clearly won't work because my hammer variable is assigned to the normalhammer class i.e. Hammer hammer; What is the best way to do this thanks.
Hammer hammer;
FastHammer hammer;//this obviously won't work because duplicate names
if(selected==1){//this was the plan but again won't work because duplication
hammer = new Hammer();
}
else if (selected==2){
hammer = new FastHammer();
}
hammerframe = hammer.HammerAnimation.getKeyFrame(hammer.hammerTime+=delta, false);
//then accessing the class variables won't work because again hammer is a duplicate field. I basically want to check what the check int is and then set hammer to the right class based on that int and the rest of the code will automatically retrieve what I need. Is this possible?
Well, here's how I would do it.
Make all your weapon classes implement some interface/superclass that will help with rendering
Keep an "armory" of weapon objects, one for each weapon type
When the player selects a weapon, set the representative existing object into a "current weapon" variable
For rendering, use the existing "current weapon" variable
Then you don't need to deal with the different types in the renderer - it's abstracted behind the interface!
First Java project - solving a Sudoku puzzle. Used SDK to create GUI first (bad idea?). GUI has 9x9 grid of square JButtons. Added handlers (81!) such that 'click' cycles values '_','1',...'9'. Named buttons in grid to reflect position (also painful). To solve puzzle implemented 9x9 array of Tile objects. Tiles to mirror state of respective JButtons (text value, etc). Want to use array of Tiles to solve puzzle. To use get/setText methods to r/w from array to/from JButtons. Hit wall!! Can't find way to reference JButtons. Hoped to create String representing JButton variable name (easy enough) then magically convert (type casting?) to reference JButton object. Not possible? A String is a String is a...? I have an object in memory (JButton) I can't reference dynamically? Approaches seen (tic-tac-toe, etc.) create an array of JButtons to access by index. Don't want to do this as it takes away from simplicity of using swing. The SDK generated source code is ~2000 lines already! Use hash to map objects to objects? Ideally each Tile object will map to respective JButton when created. Hopefully enough detail here to explain what I am 'trying' to do. Is this case where pointers would be nice? Is this a downfall of using SDK for GUI? Shortcoming in Java? Can anyone recommend approach to this (tricks or tips)?? Thanks!!
Array of Objects extending JButton is way to go. Learned much here and many thanks to all who contributed!! For newbie to Java to think an extensive swing UI is an easy approach is foolish. Took me a few weeks to learn basics of JComponents. I still use 'Window Builder' but only for the most basic interface. Want to challenge a new student? Let him/her try to tackle Sudoku as first project! Now that I have conquered this UI I feel on top of the world and no problem is beyond my reach! THANKS AGAIN!!
so here's the problem. I have a JDialog box that consists of 3 combo boxes, a text field, a few buttons and a JTable. The JTable information is filtered based on the text field and combo boxes, so for instance it starts with all of the data and gets shrunk down to only the data that starts with any string value the user decides.
What's happening though is that while the values filter correctly, if I click in the JTable (in the white space, where there are no rows) then the rows that were deleted show up, like they were invisible until I clicked on them. I've tried almost everything:
I've tried re-creating the table every time filter is clicked (bad hack that didn't even work), I've called all of the repaint, revalidate, firechanged methods, I rewrote the dialog from scratch to make sure I didn't do any stupid mistakes (if I made one I didn't find it at least), and I've tried putting them on separate threads. The only fix I haven't tried is using a swing worker, but that's because my filtering was a little too complicated for me to figure out what goes where and how to extend the swing worker correctly. The GUI is generated by netbeans (bleh), and has worked in my other dozen or so JDialogs just fine (perfectly in fact). Here's the method that doest the filtering, if any of you can help it would be greatly appreciated.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
nameFilter = "task1";
javax.swing.table.DefaultTableModel dm = (javax.swing.table.DefaultTableModel)jTable1.getModel();
tempParameters = parameters;
String currentString;
int rowNumber = 0;
while (dm.getRowCount()>rowNumber){
currentString = (String)(jTable1.getValueAt(rowNumber,1));
if(!nameFilter.equalsIgnoreCase(currentString.substring(0,nameFilter.length()))){
dm.removeRow(rowNumber);
parameters--;
}
else rowNumber++;
}
parameters = numOfRows;
}
Update, I also implemented the filter from the comment below, and while it filtered out the correct data, it had the exact same problem. In the future I will probably use this filter feature though, so thanks.
Another update, the code is still failing even after removing everything but this chunk, and all (at least I believe..) I am doing here is doing a simple remove row call. Hope this helps a bit.
Have you tried creating a new Model every time you want to filter, instead of clearing it by deleting rows? Create new model, copy relevant rows to new Model, set new Model in table. Really shouldn't be necessary, but it might be a quick fix.
Also, I really have to wonder why you're calling toLowerCase on two strings when you're using equalsIgnoreCase to compare them.
So long as this method is called from the EDT I don't think there would be a threading problem. Try using
SwingUtilties.isEventDispatchThread()
to make sure.
If you look at the API for DefaultTableModel, updates are being sent to your JTable which will repaint itself, so I don't think that is the problem.
I would guess that it is a logic problem. If you can extract the logic into separate methods it will be easier to test and verify whether it is updating the model as you expect.
Couple of observations:
If the filter happens to be larger than the string content of the row, it'll throw in the substring call
Calling the dm.removerow is generating a bunch of tablerowsdeleted events.
You're asking for a rowcount from the model, yet are getting the value through the table (a little inconsistent, if the model gets wrapped around another model you might be acting upon different rows), so instead of jtable1.getvalueat, use the dm.getvalueat.
I think what might be happening is that as the events get fired I see there are repaint and revalidate events fired in the JTable, these can be trampling over each other as they get enqueued in the EDT.
What I would suggest is to create a new datamodel, add the rows that you want to keep, and then reassign it to your jTable1.setModel(newDm);
Also to watch for is if someone else is modifying the model while you're in your eventlistener.
Hope this helps
I'm currently using net beans with Java to work on a senior project. Essentially the program is going to create word search puzzles.
While I'm still a few weeks from needing a solution, I'm having difficulty thinking of a possible control that could display a word search puzzle (not to be mistaken for a crossword puzzle).
My initial thought would be to have a grid of subclassed JPanels stored in another subclass of JPanel [as a 2D array, or something].
You could then attach MouseListeners to the grid cell JPanels if you need to detect if they've been clicked on, or whatever
Might give you an idea
brainjar - Wordsearch (source at bottom of page)
What do you mean by control? Maybe something like a JTable + Custom ListSelectionModel