Run method when initialize class

Asked

Viewed 326 times

0

I have a class called ligacao and when I initialize it (inside a button) I want another method that is within that class( that is started in a third class) to re-export and change from Observablelist.

Class ligacao (the boolean b is what changes the Observablelist):

class ligacao {
    protected static boolean b;
    public licacao(boolean b){
        this.b = b;
    }
    static FilteredList<Person> filtrar;
    public static FilteredList get(ObservableList<Person> obs, ObservableList<Person> obs2){
        filtrar = new FilteredList<>(obs, p -> true);
        if(b == true){
            filtrar.removeAll(obls);
            filtrar = new FilteredList<>(obs2, p -> true); 
        }else{
            filtrar.removeAll(obs2);
            filtrar = new FilteredList<>(obs, p -> true);
        }
        return filtrar;
    }
}

Class in which class ligacao is initialized:

    carne.setOnAction((Carne) -> {
        try {
            boolean b = false;
            System.out.println(b);

            if(carne.getText().endsWith("Carnê")){
                carne.setText("Tabela");
                System.out.println(b);
                b = true;
                System.out.println(b);
            }else{
                carne.setText("Carnê");
                System.out.println(b);
                b = false;
                System.out.println(b);
            }
            System.out.println(b);
            new ligacao(b);
            System.out.println(b + "\n");
        } catch (Exception e) {
            e.printStackTrace();
        }

    });

(third class) Where to initialize the method get class ligacao:

FilteredList<Person> filtrar = ligacao.get(obs(), obs2());

The problem that does not change the method get.

What I do?

  • A method is possible in JAVA Static use an attribute not Static? For that to be possible, I’m thinking C#, would be to declare b as public static boolean b;

  • That’s how I ended up erasing.

  • I believe that your code does not Compile. A constructor cannot access a static variable. Also, it is under the wrong name.

  • I’m sorry I put the code missing some parts, but the code compiles.

  • 2

    @Eduardofernandes There is no rule prohibiting a constructor from accessing a static variable. It is true that this is not a good practice of programming, but the compiler and the JVM accept this normally.

  • Haha truth, really allows :)

  • @ramaral the this.b = b; compiles yes, because it is allowed to access a static field using a variable instead of the class name (in this case, the variable is the this). However, this is bad programming practice and should never be done, but the language does allow.

  • 1

    @Victorstafusa My comment did not refer to that. At the time the field b nay was declared static and was accessed in the static method get.

Show 3 more comments

1 answer

3


Let’s see your first class:

class ligacao {
   // ...
   public licacao(boolean b){
   // ...

Here we have a build error, because the constructor name should be ligacao, and not licacao. Also, the naming convention dictates that class names begin with uppercase letters, and disobeying this convention is not a good idea.

A little further down:

filtrar.removeAll(obls);

There is no variable obls. I think you mean obs.

Also in this method:

if(b == true){

Please, NEVER compare a boolean expression or variable with == true or == false. This is bad programming practice. Instead, just use it like this:

if (b) {

And if I wanted to compare it to false, just use that:

if (!b) {

The method also has as a return FilteredList raw without the generic type instead of FilteredList<Person>. The compiler must be giving some warnings of types rawtypes and unchecked because of that.

Looking where you use the class ligacao out of it, we have these two places:

new ligacao(b);
ligacao.get(obs(), obs2());

In the first case, the ligacao newly created will not be used for anything and will be lost to be devoured by the garbage collector. The only effect of this will be to change the value of the static variable b (that I see no point in being protected instead of private). In the second case, the method get is static. As a conclusion, instances of the class ligacao are useless, and therefore have no sense of being instantiated. The constructor you used is nothing more than a Setter disguised, and using constructors for that is something hideous. The suggestion in this case would be to eliminate the constructor and use a Setter static:

class Ligacao {
    private static boolean b;
    public static void setFlag(boolean novoValor) {
        b = novoValor;
    }
// Na segunda classe:
Ligacao.setFlag(b);

Let’s take a look at the code that came out of second class, and try to track down what the value of b hers:

carne.setOnAction((Carne) -> {
    try {
        boolean b = false;
        System.out.println(false); // Escrevia b, mas b é sabidamente false.

        if(carne.getText().endsWith("Carnê")){
            carne.setText("Tabela");
            System.out.println(false); // Escrevia b, mas b é sabidamente false.
            b = true;
            System.out.println(true); // Escrevia b, mas b é sabidamente true.
        }else{
            carne.setText("Carnê");
            System.out.println(false); // Escrevia b, mas b é sabidamente false.
            b = false; // Não faz nada, pois b já é false.
            System.out.println(false); // Escrevia b, mas b é sabidamente false.
        }
        System.out.println(b);
        Ligacao.setFlag(b);
        System.out.println(b + "\n");
    } catch (Exception e) {
        e.printStackTrace();
    }

});

Let’s simplify it then, apart from the System.out.println unnecessary and unnecessary instructions:

carne.setOnAction((Carne) -> {
    try {
        boolean b = false;
        if (carne.getText().endsWith("Carnê")) {
            carne.setText("Tabela");
            b = true;
        } else {
            carne.setText("Carnê");
        }
        Ligacao.setFlag(b);
        System.out.println(b + "\n");
    } catch (Exception e) {
        e.printStackTrace();
    }
});

We can simplify it a little bit more if we notice that b will only be true if the condition of the if is true and with this we can use it directly as the value of b:

carne.setOnAction((Carne) -> {
    try {
        boolean b = carne.getText().endsWith("Carnê");
        carne.setText(b ? "Tabela" : "Carnê");
        Ligacao.setFlag(b);
        System.out.println(b + "\n");
    } catch (Exception e) {
        e.printStackTrace();
    }
});

Here, it is still necessary to question the name of the lambda parameter: Carne. This is not an appropriate name, as this is a variable and therefore should start with lowercase letter. In addition, have two variables whose name differs only by upper and lower case, namely carne and Carne is a bad programming practice because it leaves the code very confusing. I suggest renaming the Carne for something else.

Now, coming back to your first class, you realize that you’ve forgotten the private in the declaration of the static field filtrar, but let’s take a look at what method get makes (already applied the corrections I suggested before):

private static FilteredList<Person> filtrar;
public static FilteredList<Person> get(ObservableList<Person> obs, ObservableList<Person> obs2) {
    filtrar = new FilteredList<>(obs, p -> true);
    if (b) {
        filtrar.removeAll(obs);
        filtrar = new FilteredList<>(obs2, p -> true); 
    }else{
        filtrar.removeAll(obs2);
        filtrar = new FilteredList<>(obs, p -> true);
    }
    return filtrar;
}

If b is true here’s what happens:

  1. Create a list of all elements of obs and assigns it to the static variable filtra, therefore missing the previous reference of the list no matter what it was.
  2. Removes all elements of obs which are in the list (and therefore all elements), which results in an empty list.
  3. Create another list of all elements of obs2. The previous list is lost to the garbage collector, and so the work done on it in steps 1 and 2 has been wasted.
  4. Returns the list with the elements that were in obs2.

If b is false:

  1. Create a list of all elements of obs and assigns it to the static variable filtra, therefore missing the previous reference of the list no matter what it was.
  2. Removes all elements of obs2 which are on the list, which results in a list with the elements of obs who are not in obs2. If there is no element on both lists, it will do nothing.
  3. Create another list of all elements of obs. The previous list is lost to the garbage collector, and so the work done on it in steps 1 and 2 has been wasted.
  4. Returns the list with the elements that were in obs.

Note that in both cases, the list that is kept at the end is irrelevant, because the way the method get has been coded, any attempt to access the contents of this list will necessarily cause it to be lost.

All this would be so much simpler:

public static FilteredList<Person> get(ObservableList<Person> obs, ObservableList<Person> obs2) {
    return new FilteredList<>(b ? obs : obs2, p -> true);
}

And that’s how your code ends up:

class Ligacao {
    private static boolean b;

    public static void setFlag(boolean novoValor) {
        b = novoValor;
    }

    public static FilteredList<Person> get(ObservableList<Person> obs, ObservableList<Person> obs2) {
        return new FilteredList<>(b ? obs : obs2, p -> true);
    }
}
carne.setOnAction(x -> {
    try {
        boolean b = carne.getText().endsWith("Carnê");
        carne.setText(b ? "Tabela" : "Carnê");
        Ligacao.setFlag(b);
        System.out.println(b + "\n");
    } catch (Exception e) {
        e.printStackTrace();
    }
});
FilteredList<Person> filtrar = Ligacao.get(obs(), obs2());

Finally, some people may find that accessing the static field using this causes a build error. This is not true because it is allowed to access a static field using a variable instead of the class name and in this case the variable is the this). However, this is bad programming practice and should never be done, but the language allows.

And also accessing a static variable from within the constructor is perfectly valid in the Java language. Most of the time (not always, there are some exceptions), doing this is not good programming practice and tends to leave the code bad and prone to occurrence of bugs, but the Java language allows.

  • These errors in the names of the variables was because I was advised to use simpler names and when I changed it didn’t work very well. And that part carne.setText(b ? "Tabela" : "Carnê"); was not aware of it. But even correcting the code, it goes every time I click the button it will change the Person(obs()) standard for each other Person(obs2())?(Here is the same Person) But thanks for having me over on the this and other things.

  • @lucasdaniel In its third class, what methods obs() and obs2() return?

  • They are a read in the database and return ObservableList<Person>, each is a database table.

  • Do you have any idea how to do that?

  • This started working when I used FXML, and since all (or almost all) the code will be in one class it is done like this:tableview.getItems().clear() and tableview.getItems().addAll(b ? obs : obs2). Thanks for answering and sorry for taking so long to mark how to hit.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.