override graphstream's DefaultMouseManager - java

I'm using GraphStream to show a map of an area and I've tried to inherit from the default MouseManager DefaultMouseManager and to override the mouseClicked method so that when clicking on a node the following will happened:
node's color will change.
node's label will show.
node's data will show in terminal.
I do know that the method works because the node's data does get printed to terminal, but I think some other mouse event repaint the node and rehide the label so they doesn't change when clicking on a node.
here is my MouseManager's code:
public class CustomMouseManager2 extends DefaultMouseManager {
protected View view;
protected GraphicGraph graph;
private GraphicElement focusedNode;
#Override
public void init(GraphicGraph graph, View view) {
super.init(graph, view);
.
.
.
}
#Override
public void mouseClicked(MouseEvent e) {
GraphicElement currentNode = view.findNodeOrSpriteAt(e.getX(), e.getY());
if(currentNode != null){
OGraph graph = OGraph.getInstance();
Random r = new Random();
currentNode.setAttribute("ui.style", "fill-color: red; text-mode: normal;");
ONode oNode = graph.getNode(Long.parseLong(currentNode.getLabel()));
System.out.println(oNode.toString());
}
if(focusedNode!= null)
focusedNode.setAttribute("ui.style", "fill-color: black;size: 10px, 10px; text-mode: hidden;");
focusedNode = currentNode;
}
}
I've tried to check what methods from the base class DefaultMouseManager are called after my mouseClicked is called so I could override them too, but there was to many of them to follow.
Is there an elegant way to make sure my changes will execute after all other method from the base class?

Is there an elegant way to make sure my changes will execute after all other method from the base class?
Read the documentation and look at the code in DefaultMouseManager. I googled DefaultMouseManager, looked at the documentation, went through the inheritance of the different interfaces until I got to MouseListener, which describes the order of operations. Then I looked at mouseClicked and mouseReleased since they would be called last, mouseClicked is empty so that leaves mouseReleased and the methods that are called in it.

So, something similar to this question has happened, the mouseClicked() method was called twice.
In my code, I repaint black the previous node and hide its label after a new node is clicked. And for that reason, when the mouseClicked() method was called twice then the first call changed the node`s appearance and the second one changed it back.
In that case, an easy fix will be to check if the previous node and current node are the same. replace this if(focusedNode!= null) with this
if(focusedNode!= null && focusedNode != currentNode)
but a more straightforward solution will be to understand why the method is been called twice.
My guess is that it has something to do with the inheritance but I'm not sure.

Related

How would I retrieve the coordinates of my actor subclass in order to place a new actor at the location?

public void move()
{
//if (this.getWorld().getObjects(Marker.class).isEmpty())
Dog bill = getOneIntersectingObject(Dog.class);
Marker bone = getOneIntersectingObject(Dog.class);
if (bone == null);
{
Marker bone= new Marker();
getWorld().addObject(marker.getX(), marker.getY());
}
super.move(1);
}
I'm trying to reference the location of my current actor subclass (dog) in order to place a marker(bone) of another subclass at the coordinates it is located at.
You can retrieve the coordinates of the actor by calling getX() and getY(), as you do it for other actors.
If you like to call methods for the "current" actor, you might like to use this, in example this.getX(). But it is only necessary, if you need to resolve some ambiguity. Commonly you can just call the method.
public void move()
{
Dog bill = getOneIntersectingObject(Dog.class);
Marker bone = getOneIntersectingObject(Marker.class);
if (bone == null)
{
Marker marker = new Marker();
getWorld().addObject(marker, getX(), getY());
}
super.move(1);
}
Changes necessary as obvious from the shown excerpt:
The parameter of the second getOneIntersectingObject() is Marker.class, because you seem to want this.
No semicolon after the parenthesis of the if. If you don't remove it: This semicolon is an empty statement, so the if will have no effect. The block between the braces following it will always be executed.
Rename the second bone as marker to show your intention. (It would "shadow" the "outer" bone, additionally, but this is no problem here.)
Call addObject() with the right parameters: the object to place (the new marker), and its coordinates (retrieved by calling getX() and getY()).

Java class variables are updating inconsistently between classes

In general, my goal is to draw lines defined by the user's cursor. To accomplish this, I am figuring out the calculations for those lines in one class, and then updating the class that paints the lines with those new values. Overall I want to access a list of line segments, a list of nodes, and the current abstract "node" that the cursor is located at. (Nodes and Line Segments are my own defined classes). The class in which the lines are drawn is called GraphicsPanel.
I set up access between the classes as follows:
public class MainClass extends JFrame {
protected static ArrayList<LineSegment> lineList = new ArrayList<LineSegment>();
protected static ArrayList<Node> nodeList = new ArrayList<Node>();
protected static Node current = new Node();
// Code for calculations and user interactions
{
GraphicsPanel displayPanel = new GraphicsPanel();
// Values are updated
displayPanel.revalidate();
displayPanel.repaint();
}
}
public class GraphicsPanel extends JPanel {
private ArrayList<LineSegment> lineList = package.MainClass. lineList;
private ArrayList<Node> nodeList = package.MainClass.nodeList;
private Node current = package.MainClass.current;
public GraphicsPanel() {
}
public void paint(Graphics g) {
// Paint lines and other shapes
}
}
While the lineList and nodeList objects get correctly updated when a new LineSegment or Node is added to the list, the current Node is never updated and always shows the default of (0, 0).
As an example, within the main class, I have two mouse listeners, one for mouse clicks and one for mouse movement. They have similar functions, but the mouse click listener updates both the current Node and the lineList ArrayList of LineSegments.
displayPanel.addMouseListener(new MouseListener() {
#Override
public void mousePressed(MouseEvent e) {
Point p = e.getPoint();
current = new Node(p.getX(), p.getY());
lineList.add(new LineSegment(current, current);
// Don't worry, the line segment gets updated (correctly) with a new end node as
// the cursor moves around the window
displayPanel.revalidate();
displayPanel.repaint();
}
});
When I click on the window to create lines, the lines show up as expected but the current Node remains at (0, 0). I am completely flabbergasted by this, since it seems like only one of the variables is updating, even though both are written to update in basically the same way: I modify the instance of the class variable in the main class, which should modify the instance of the variable in the GraphicsPanel class.
I appreciate any help with this conundrum and welcome suggestions for what's wrong, as well as better ways to approach this application.
You don't modify the instance, you create a new instance, replacing the old. This means that GraphicsPanel.current will keep pointing to the original instance, but MainClass.current will point to a new distance.
If you did something like instance.setY(p.getY()), it would modify the single original instance that both classes are pointing to.
Your MouseListener adds objects to the Main class list.
Then it assigns a different new object to the panel reference current. But that doesn't change the Main class refence!
You could just not have another current reference in the panel code. Simply directly assign to the current instance that belongs to the Main class!

Java Methods when working with Swing - It is possible to call event method in another event method in same class?

so I am new to java and using right now swing. I have an method (first method) that does some code when I type in specific jField and release key.
I also have jCheckBox, so when I tick or untick checkbox it does some action, this is second method.
So I want when I tick or untick checkbox make it call my first method and first method must do it's code. But it seems I have problem and I can't call this method fro some reason.
Part of first method:
private void bruttoTextFieldKeyReleased(java.awt.event.KeyEvent evt) {
//code
}
Second method trying to call first method:
private void pensionCheckBoxStateChanged(javax.swing.event.ChangeEventevt) {
bruttoTextFieldKeyReleased();
}
Those methods were created with this menu
And this is hint, but I am not sure what I need to do, it required some KeyEvent? I just want launch one method from another, not putting any value and not returning.
Error Hint
To expand a bit on Luvy's comment, and convert it into an answer using your code.
Right now, the first method takes a KeyEvent, and looks like this:
private void bruttoTextFieldKeyReleased(java.awt.event.KeyEvent evt) {
double salaryBrutto = Double.parseDouble(bruttoTextField.getText());
double taxPensRound;
if (pensionCheckBox.isSelected()) {
double taxPens = salaryBrutto * TAX_PENS;
//more code
Going by the screenshots, it looks like you most likely auto-created it from a GUI builder, and are not using the KeyEvent evt parameter. You aren't able to call this method without passing in a KeyEvent, which is why pensionCheckBoxStateChanged cannot call it.
Luvy's suggestion would be to create a new method out of the bruttoTextFieldKeyReleased button, so afterwords you would have two methods:
private void bruttoTextFieldKeyReleased(java.awt.event.KeyEvent evt) {
calculatePensionInformation();
//maybe do something with evt later on
}
and
private void calculatePensionInformation() {
double salaryBrutto = Double.parseDouble(bruttoTextField.getText());
double taxPensRound;
if (pensionCheckBox.isSelected()) {
double taxPens = salaryBrutto * TAX_PENS;
//more code
}
At this point, you could change your existing second method to be:
private void pensionCheckBoxStateChanged(javax.swing.event.ChangeEventevt) {
calculatePensionInformation();
}
And it would work as expected, since calculatePensionInformation requires no parameters, and you are passing in no parameters.

problems with returning a value java

I have this method that contains a MouseEvent. How do I return the idu variable?
it is like a method in a method or how to call it and I can't figure out how top return the idu variable.
public int getId() {
int idu;
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1) {
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
Object record = data[row][0];
idu = (Integer) record;
}
}
});
return idu;
}
In nearly all cases the 'listener' pattern involves registering listeners with methods that do not have return values. In general a return value from a listener is meaningless because it's being returned to caller that has no context about what to do with it.
It seems to me you have misunderstood a few things in the code you have posted:
1. it makes little sense to register a listener in a 'getter' method. The listener needs to be registered once, generally in the class's constructor
2. registering a listener doesn't do anything on its own: it just tells the handler to call your method when an event occurs (in this case clicking a mouse).
3. unless you are reusing the listener in several places (which you are not in this code fragement because it's an anonymous class) then you don't need to get the event source - you should already have it as a member field in the class.
So the answer in your case is that your JTable should be a member field of your class. Then the getId method need only return the selected row of the table. There is no need to register a mouse listener at all as the selected row is available in JTable without any additional work.
Think about the following question:
When do expect to have the idu value ready for use - when the method getId() finished running, or when the user clicked the mouse button over the table?
What your code actually do is to register an event listener, kind of like setting an alarm or scheduling a task for later, and then going to sleep, or back to do whatever other task you need to do now.
The value of idu doesn't neccessarily exist when you exit the getId() method, because the code in the mouseClicked() method didn't neccessarily executed yet. It will only execute when the event actually happen.

Simplest way of creating java next/previous buttons

I know that when creating buttons, like next and previous, that the code can be somewhat long to get those buttons to function.
My professor gave us this example to create the next button:
private void jbtnNext_Click() {
JOptionPane.showMessageDialog(null, "Next" ,"Button Pressed",
JOptionPane.INFORMATION_MESSAGE);
try {
if (rset.next()) {
fillTextFields(false);
}else{
//Display result in a dialog box
JOptionPane.showMessageDialog(null, "Not found");
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
Though, I do not really understand how that short and simple if statement is what makes the next button function. I see that the fillTextFields(false) uses a boolean value and that you need to initialize that boolean value in the beginning of the code I believe. I had put private fillTextFields boolean = false; but this does not seem to be right...
I'm just hoping someone could explain it better. Thanks :)
Well, fillTextFields(true); is a function call and when you pass in a true/false flag it does some things (you have to see the code inside the function in order to find out exactly what it does).
The field declaration private fillTextFields boolean = false; is invalid, you're supposed to provide the type before the name, e.g.: private boolean fillTextFields = false;. Aside from the invalid syntax that flag really doesn't do anything, especially if you're not using it anywhere.
I don't understand what else you expect to see in the jbtnNext_Click() method... when you declare your button and it gets clicked on the UI, then this method gets invoked. It doesn't make the button work, the button works even when you have nothing in the jbtnNext_Click() method. For example:
private void jbtnNext_Click() {
// The button will still work, but it simply won't do anything
}
Getting a button to function depends on what you view as a functioning button. What is supposed to happen when you click next/previous?
Update:
I thought that I needed the boolean
declaration to make the
"fillTextFields(false)" work.
Was the fillTextFields method given to you somewhere? If it was, then you don't need to declare anything, much less a variable. If it's already provided, then you just call the method, that's all. If it's not provided then you need to declare it:
private void fillTextFields(bool shouldFill)
{
if(shouldFill)
{
// fill the text fields
}
// possibly have an else statement if you need to do something else here
}
Otherwise what you see in that function is all you need to do in order to go to the next record in the database.
I think that the code provided is a bit short to provide a good explanation, posting the code for fillTextFields would be of more help.
What I can guess that the program is doing is that it is retrieving some data from a database. The next button allows the program to iterate through the items that have been returned.
Once that the next button is pressed, a message box is shown to let you "know" that the button has indeed been pressed.
rset.next returns true of there is another element in the list (retrieved from the database), or false if there isn't.
If it returns true, you are calling the fillTextFields methods, which I guess displays the data on screen (even though without the code I can just speculate). If there isn't anything left, a message box displaying "Not Found" is shown.
With regards to your question about
private fillTextFields boolean = false;
fillTextFields is a method, and you cannot assign values to methods. Also, in Java, when declaring both methods and variables, the type is written before the name, such as
private int number;
public float myMethod() { }
The next button won't do anything unless you register an action with the button. What I mean is, wherever your next button is defined looks something like this:
private JButton nextButton = new JButton("Next");
This creates a button that has the label, 'Next'. There might be some additional code for positioning the button. In order for that button to do anything when it is clicked, it needs to have an Action set on it, or it has to have an ActionListener added to it. Many times, the class that is creating the button implements ActionListener and has a method to respond to the click, something like:
nextButton.addActionListener(this);
...
...
...
public void actionPerformed(ActionEvent e) {
// some method implementation
}
The actionPerformed method is called when the button is clicked, AS LONG AS you've registered the action listener on the button. Is anything like this present in the code from your professor?

Categories

Resources