I have a main class where the UI is located and that it instantiates another class, where the logic is located. I create the instance of the logic only when a button is clicked.
private void computeActionPerformed(java.awt.event.ActionEvent evt) {
//A STAR MISPLACED
EightPuzzle ep2 = new EightPuzzle(stringToInt(initial),"mis");
solution = ep2.getSolution();
aMisplacedSpace.setText(ep2.getNodesTraversed()+" nodes"); // I would like to display this during the search and not just after
setCurrentTilesAStarMisplaced(solution.size()-1);
}
The problem is that I have to display the number of nodes traversed during a particular instance into some JLabel in the UI. I guess my current structure does not allow me to do so. Is there a work around on this?
Related
I have got 2 Pane. The first pane is main menu, there is only Rectangle in its children. The second pane is my game. When I go to main menu I use following method to clear game pane
//Fighting fighting = new Fighting();
//There is Pane fighting in fighting
if(fighting != null) {
fighting.getFighting().getChildren().clear();
fighting = null;
System.gc();
}
When I scene.setRoot(fighting.getFighting()); and don't do anything(don't hover on objects which has OnMouse...(), don't call methods which move player) and exit to main menu(by clicking Esc)
scene.setOnKeyPressed(event -> {
if (event.getCode()==KeyCode.ENTER) setFighting();
if (event.getCode()==KeyCode.ESCAPE) setMainMenu();
});
In such case I don't have problems with memory and GC deletes useless objects.
But if I click/hover on any objects with listeners or call move() on player, GC won't delete the same object. And if I re-enter game pane and use it normally, GC will delete objects from prevoius session and won't delete them from current session
In my profiler I've found out that references on these useless objects are stored in Pane which is in one of ArrayLists in anonymous class MouseHandler in Scene. Can't add image good.
Also I've found out that there are only 2 Pane in heap. One of them is mainMenu. I've understood it because there is only Rectangle in its children. And the second's pane's children equals children.size() == 0.
It's code from Scene & MouseHandler
private MouseHandler mouseHandler;
class MouseHandler {
/* lists needed for enter/exit events generation */
private final List<EventTarget> pdrEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> currentEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> newEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> fullPDRCurrentEventTargets = new ArrayList<EventTarget>();
private final List<EventTarget> fullPDRNewEventTargets = new ArrayList<EventTarget>();
private EventTarget fullPDRCurrentTarget = null;
}
Is it possible to clear these collections or to fix memory leak? Thanks for answers
Well technically you may use the Reflection API to get access to that list and clear it manually, but i’m not sure would it be safe to do so.
AFAIK that pdrEventTargets list is holding components chain that represents a path from the scene to a component that was clicked the last and that list is being refreshed at each click. So if you’re in situation when you have replaced a branch of componens tree and still seeing a bunch of references on removed components in that list, these are will be removed from pdrEventTargets on the next click handling by MouseHandler. At least it behaves exactly like that while i debugging at jdk 1.8. Probably you have exactly the same behavior, so there should be no reasons to worry about, at least if these staled components do not holding a references to some “heavy” objects that should not live after these components was removed. In that case you should remove that references as part of the process of components remove.
I'm trying to build a dynamic web app in GWT, when widgets are added to the screen I remember their 'name' by setting the Widget.setId, when I want to replace part of the page, I can find the element in question via DOM.getElementById('name'), and its parent using DOM.getParentElement(), and then remove its children.
Now I have a com.google.gwt.dom.client.Element object (the parent). What I want to do is turn this back into a GWT object - in fact it'll be something derived from Panel, so I can add additional Widgets.
How do I go from the Element object back to a Panel object ?
I totally accept I could be going about this the wrong way, in which case is there a better way?
I think your approach to remove widgets from the DOM using DOM.getElementById('name') is not the proper one.
On your case (I am just figuring out what you do), I would keep Java Objects references instead of accessing to them using the DOM.
For instance:
HorizontalPanel panel = new HorizontalPanel();
Widget w = new Widget();
//We add the one widget to the panel
panel.add(w);
//One more widget added
w = new Widget();
panel.add(w);
//Now we remove all the widgets from the panel
for(int i = 0; i < panel.getWidgetCount(); i++){
panel.remove(panel.getWidget(i));
}
UPDATE
Based on your comments, I would propose the following solution.
I suppose that you are storing widgets on HorizontalPanel, just apply this solution to your concrete case.
I propose to use customized class which inherits from HorizontalPanel and add a Map there to store relationship between names and widgets.
public class MyHorizontalPanel extends HorizontalPanel {
private Map<String, Widget> widgetsMap;
public MyHorizontalPanel(){
super();
widgetsMap = new HashMap<String, Widget>();
}
//We use Map to store the relationship between widget and name
public void aadWidget(Widget w, String name){
this.add(w);
widgetsMap.put(name, w);
}
//When we want to delete and just have the name, we can search the key on the map.
//It is important to remove all references to the widget (panel and map)
public void removeWidget(String name){
this.remove(widgetsMap.get(name));
widgetsMap.remove(name);
}
}
Unfortunatly I am unable to provide code to this site due to where I work. With that said I will be as detailed as I can. I am working on using aan XML file to populate a JcomboBox based of the "Name" element. I have that part working. The way I am doing this is by using DOM method and I create in Object for each of the Nodes and then I uset set methods to grab the attributes that I require.
Where I am now is I need to populate a text field based off of what was selected. I am struggling to figure out how to associate what is selected to what I need. For instance let say I have a node called "Reference_Point_ID" and I needed to pull the child node called "Latitude" to populate the JTextField. How would I associate the child node with the parent node to pull the correct data?
Again I am sorry I cannout provide the code but any help will be much appreciated. Thank you.
UPDATE - SOLUTION
For anyone else that may need this info.
In order to pull the data for what I needed into the JComboBox I had to modify the model like so:
public TestReferencePointXMLReaderGUI()
{
initComponents();
ReferencePointReader referencePointReader = new ReferencePointReader("path to your xml file");
List<ReferencePointObject> listOfData = referencePointReader.getData();
DefaultComboBoxModel<ReferencePointObject> model =
(DefaultComboBoxModel<ReferencePointObject>) jComboBoxRefPointSelector.getModel();
for (ReferencePointObject referencePointObject : listOfData)
{
model.addElement(referencePointObject);
}
}
The following shows how I changed the data in the text fields based off of what was selected. There is something I would like to mention. Unless you want the ItemStateChanged to return the previous selection as well as the new selection you need to be sure to add the if check statement.
private void jComboBoxRefPointSelectorItemStateChanged(java.awt.event.ItemEvent evt)
{
if (evt.getStateChange() == ItemEvent.SELECTED)
{
Object selected = jComboBoxRefPointSelector.getSelectedItem();
ReferencePointObject selectedReferencePoint = (ReferencePointObject) selected;
jTextFieldLat.setText(selectedReferencePoint.getLat());
jTextFieldLong.setText(selectedReferencePoint.getLng());
}
}
I have a problem for a month ago :S .This is it:
I have 3 classes:
Class 1:
TabbedPane with a MouseListener, when someone click on a tab, the mouse listener change a variable called "update".
This class have a method like this:
public boolean getUpdateMenuState(){
//Creates the update variable
boolean update = false;
//If a update is necessary
if(needUpdate = true){ //Need update is defined at top of the class
//Reset the update variable
needUpdate = false;
//Set the getUpdate variable to true
update = true;
System.out.println("The menu needs to be updated");
}
//return the update
return update;
}
The second class, is the main:
This class needs to know if the variable needUpdate changes, I have this method:
private void updateMenu(){
//Create a variable update
boolean update = false;
//Set the variable update to the get state
update = myTabbedPane.getUpdateMenuState();
//If a update is requiered, re-add the menu
if(update){
menu.addMenu(); //Call the third class that have the method addMenu
}
}
My problem is that I need to know constantly if the variable needUpdate is changed, and I don't know how to implement my own listener to do it.
I can't call the third class directly in the first class because I want to centralize the control on the second class.
Please, if someone can help me I'll be grateful.
This is a classic example where an Observer pattern is the ideal solution. Refer to this Implementing Observer Pattern post for the details of how to implement the Pattern.
PS: just saw your reply to one of the answers;
Best in your situation is to use a Class instead of the boolean variable and you can extend that class.
I would think that this is a classic case for using the Observer Design Pattern. Class 2 would be the Observer for things happening on the Subject i.e. Class 1 and do what it needs to do when it gets notified i.e. call addMenu() on Class 3.
I have a JList, wich must display more than 3000 items. I wish to have "visible" around 100 items in the list, and when you scroll and getting close to the end (or begining) of the "visible" items the next portion (around 50) must be loaded in the list. Is there any simple way of doing this?
The list is rendering only the visible part. So there is no overhead from this point of view. If you want lazy loading - use custom models.
From this page :
You can write your own class that extends AbstractListModel or AbstractTableModel so that you can provide the needed data when necessary. The following example shows the usage of AbstractTableModel.
no there are no simple way for that, you have to implements Pagination(s)
easiest job when is managed by Databases engine, most of then support paginations directly
in the Model, but I never seen workaround for XxxListModel, use JTable with one Colum instead, there are some good workaround for Pagination for JTable
I have a JList, wich must display more than 3000 items.
Huh. You make that sound like a big number. Here is a list holding (and displaying just fine), more than 30 thousand items.
import javax.swing.*;
class BigList {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int bigNumber = 30001;
String[] bigData = new String[bigNumber];
for (int ii=0; ii<bigNumber; ii++) {
bigData[ii] = "String " + (ii+1);
}
JList list = new JList(bigData);
list.setVisibleRowCount(5);
JOptionPane.showMessageDialog(null, new JScrollPane(list));
}
});
}
}