Accessing "this" from an anonymous Java subclass [duplicate] - java

This question already has answers here:
Getting hold of the outer class object from the inner class object
(7 answers)
Closed 6 years ago.
I'm trying to modify the behavior of JToolBar to allow it to dock to more than one JPanel. As part of this exercise, I need to override the method getDockingConstraint which I tried to do with an anonymous class using a definition very similar to the original.
The problem is that the original implementation references this several times which I thought would be fine, but I must be missing something because the IDE reports that this.dockingSensitivity is not visible to the anonymous class.
Is there a simple change here, or should I skip this approach and just create a full subclass of BasicToolBarUI? Or maybe there is a better approach entirely to modifying JToolBar's docking capability?
public MultiDockToolBar() {
setUI(new BasicToolBarUI(){
#Override
private String getDockingConstraint(Component var1, Point var2) {
if(var2 == null) {
return this.constraintBeforeFloating;
} else {
if(var1.contains(var2)) {
// Breaks here when using this.:
this.dockingSensitivity = this.toolBar.getOrientation() == 0?this.toolBar.getSize().height:this.toolBar.getSize().width;
if(var2.y < this.dockingSensitivity && !this.isBlocked(var1, "North")) {
return "North";
}
// Check East
// Check West
// Check South
}
return null;
}
}
});
}

dockingSensitivity is a private field inside BasicToolBarUI class. You will not be able to directly alter this. If you still want to edit and face the potential consequences, you can use Java Reflections library.

Related

Difference between ()->object.method() and object::method when it comes to null object [duplicate]

This question already has answers here:
java.lang.NullPointerException is thrown using a method-reference but not a lambda expression
(2 answers)
Closed 3 years ago.
I work with some legacy code that goes back decades and has a lot of objects where a field being null means "we don't have that information". As such, it has a lot of methods where it wants to do some math on fields, but only if they are not null. This leads to many ugly if statements that look like a procession of null checks, and happen multiple times per method for various length sets of things that can't be null if the contents are going to be used.
For example
public class Foo
{
public Bar getBar()
{
//returns a Bar object that may or may not be null
}
}
Then, elsewhere
if(foo1 != null && foo1.getBar() != null && foo2 != null && .... etc) {
//do math with foo1.getBar(), foo2.getBar(), etc...
}
Anywho, I made a utility to help make these look a little nicer (and also quiet down SonarQube about too many checks in an if) by making a utility class that looks like this:
public class NullCheckUtil
{
private NullCheckUtil()
{}
public static Boolean anyNull(Object... objects)
{
return Stream.of(objects).anyMatch(Objects::isNull);
}
}
Then realized that if foo1 is null, will get NullPointerException before even going in the anyNull.
Ok, lets make it a stream, so they are not evaluated on declaration:
public static Boolean anyNull(Supplier<Object>.... suppliers)
{
return Stream.of(suppliers).map(Supplier::get).anyMatch(Objects::isNull);
}
Then if check can be
if(!NullCheckUtil.anyNull(foo1, foo1::getBar, foo2, foo2::getBar,.... etc){//do the math}
And my IDE seemed happy with that, no problems. But when I ran from console, I'd get NPE with the error claiming to be on the if line again. Whaaaa?
So I did some digging and at first thought maybe this is the reason:
Does Java's ArrayList.stream().anyMatch() guarantee in-order processing?
So I changed the anyNull again to
public static Boolean anyNull(Supplier<Object>... suppliers)
{
for(Supplier<Object> supplier : suppliers)
{
if(supplier == null || supplier.get() == null)
{
return true;
}
}
return false;
}
NOPE, still doesn't fix it (for console).
Experimenting to see what could do it I changed the if to
if(!NullCheckUtil.anyNull(()->foo1, ()->foo1.getBar(), ()->foo2, ()->foo2.getBar(), etc...)
And that works fine in IDE and also in console. Tried both in Java 8.151 and Java 8.221, same behavior.
In other words
try
{
NullCheckUtil.anyNull(()->foo1, ()->foo2, ()->foo1.getBar(), ()->foo2.getBar());
}
catch(NullPointerException npe)
{
//does not happen
}
try
{
NullCheckUtil.anyNull(()->foo1, ()->foo2, foo1::getBar, foo2::getBar);
}
catch(NullPointerException npe)
{
// *DOES* happen. What tha….?
}
So there is some difference between ()->obj.method() and obj::method lambdas in that the latter gets interpreted right away on declaration? What is that?
If the Objects you want to check are always Foo, then you can rewrite the method to:
public static boolean isAnyFooNullOrReturnsAnyGetBarNull(final Foo... foos) {
return Stream.of(foos)
.map(foo -> Objects.IsNull(foo) || Objects.isNull(foo.getBar()))
.reduce(false, Boolean::logicalOr);
}
Ideone example
Notice that this example uses an immutable class Foo. This property is essential since this guarantees that Foo::getBar() for a certain instance will always return the same Bar. If this property is not given, then the problem is not solvable in a streamified solution.
This is also the reason why the attempt of using a Producer<Bar> will not work: the first call to a producer could return a non-null value, while the second call will return a null value. Some classes behave this way, i.e. they allow only a single consumption of a resource/property.
If the parameter of the method has to be Object..., then the problem is not solvable with Streams.
Found older 100% applicable and correct answer after modifying the search terms (i had tried earlier with no luck): java.lang.NullPointerException is thrown using a method-reference but not a lambda expression
It even answers why Eclipse is behaving "nice" (Eclipse bug).

What is the purpose of NoSuchMethodException instead of returning null [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
In Java, Foo.class.getMethod("bar") declares a checked exception of type NoSuchMethodException (among others).
What is the purpose of this exception? Isn't returning null sufficient to indicate that it was not found? What information or utility does throwing an exception add? Aside from forcing the user to explicitly be aware that it's possible for it to not be found, this seems superfluous. Returning null when something doesn't exist is a common pattern in Java, and this seems to be a prime candidate for that. So what was the reasoning behind this?
It appears that the designers of Java APIs made a distinction between situations when it's OK to ask for something that is missing and situations when you are supposed to ask only for things that exist.
They decided that asking for a missing key in a Map is OK, because the content of a map is something your program controls at runtime. Therefore, designers of the class library decided that it is unreasonable to ask programmers to check if a value is present before calling Map.get, and decided to return null instead.
The list of methods in a class, however, remains static at all times during a particular run, so it becomes reasonable to ask programmers to call getMethod only for methods that do exist. There are two consequences to this approach:
You can request multiple methods without checking each one - if you have a list of methods that must exist, for example, in a plugin component, you can get their Method reflection objects without checking the return value of individual getMethod calls, and
When you do not know if a method exists, call getMethods() - You can still examine all methods without knowing their names by getting a full list from the Class object.
Here is a code example to illustrate the first point. Current API lets you write this:
class Plugin {
private final Method init;
private final Method start;
private final Method stop;
public Plugin(Class cl) throws PluginException, SecurityException {
try {
init = cl.getMethod("init");
start = cl.getMethod("start");
stop = cl.getMethod("stop");
} catch (NoSuchMethodException ex) {
throw new PluginException("Plugin is missing a required method", ex);
}
}
...
}
instead of this:
class Plugin {
private final Method init;
private final Method start;
private final Method stop;
public Plugin(Class cl) throws PluginException, SecurityException {
init = cl.getMethod("init");
if (init == null) {
throw new PluginException("Plugin is missing init method");
}
start = cl.getMethod("start");
if (start == null) {
throw new PluginException("Plugin is missing start method");
}
stop = cl.getMethod("stop");
if (stop == null) {
throw new PluginException("Plugin is missing stop method");
}
}
...
}

Difference between return and break inside ifs in a for loop [duplicate]

This question already has answers here:
Difference between Return and Break statements
(14 answers)
Closed 5 years ago.
I'm studing a code wich has this code:
public void add(StockUpdate newStockUpdate) {
for (StockUpdate stockUpdate : data) {
if (stockUpdate.getStockSymbol().equals(newStockUpdate.getStockSymbol())) {
if (stockUpdate.getPrice().equals(newStockUpdate.getPrice())) {
return;
}
break;
}
}
/* data.add mathod checks the new data against the existing data. If no change is found, the update is discarded. */
this.data.add(0, newStockUpdate);
notifyItemInserted(0);
}
I just want to know if the return and the break statements in this code are, in any way, different from each other. Because I tested a similar example outside this code and both return and break stopped the loop and terminates the function.
break stops just the loop; return stops the entire method.
The juxtaposition of break and return like this makes it quite hard to follow the logic of the add method. Consider that the following might be easier to follow:
public void add(StockUpdate newStockUpdate) {
StockUpdate stockUpdate = findStockUpdateBySymbol(newStockUpdate.getStockSymbol());
if (stockUpdate != null
&& stockUpdate.getPrice().equals(newStockUpdate.getPrice())) {
return;
}
/* data.add mathod checks the new data against the existing data. If no change is found, the update is discarded. */
this.data.add(0, newStockUpdate);
notifyItemInserted(0);
}
// On non-android, it's easier to do this with a stream/findFirst.
private StockUpdate findStockUpdateBySymbol(StockSymbol sym) {
for (StockUpdate stockUpdate : data) {
if (stockUpdate.getStockSymbol().equals(sym)) {
return stockUpdate;
}
}
return null;
}
I'd say that this is easier to follow (whilst being slightly more verbose) because it is separating out the different things that are being done: you're trying to find a matching stock symbol; and if you find that, do other stuff. Mixing that all together into the one loop obfuscates that intent.

Efficient null check for a compound object in Java [duplicate]

This question already has answers here:
is there a Java equivalent to null coalescing operator (??) in C#? [duplicate]
(5 answers)
Null check chain vs catching NullPointerException
(19 answers)
Closed 6 years ago.
A program creates a JDialog panel with multiple tabs. One of the tabs has several tables. A JTable has adjustable column width. This tab is generated under different conditions. Sometimes from the state tab is null, sometimes tab exists, but the table is null. Sometimes user haven't resized the column yet.
I am looking for a method to save the columnWidth value if user resized the column. Checking for null seems bulky in this situation:
jpanel.tab.table.width
the best method I can find is:
if( jpanel!=null &&
jpanel.jtab!=null &&
jpanel.jtab.jtable!=null && ...
Is there a better way to do this null check?
I saw this question:
is there a Java equivalent to null coalescing operator (??) in C#?
It doesn't list a solution and is quite old (Java 6-7 time). I was hoping this feature was added in later releases.
There's no way to do exactly what you want.
However, you can just throw everything into a try statement:
try {
myItem = bundle.category.subcategory.item;
}
catch(NullpointerException ignored) {}
Note that this looks very hacked, and it's rather poor coding practice. Your current solution is probably the best approach in terms of clarity.
Edit: I tried posting another Anwser but the button is greyed out, so I'll put it here:
Feels like repeating same code many times, when you should use a for loop
You can indeed use a for loop, but that will invovle Reflection and much boilerplate code. Imagine something like this:
static boolean checkDeepNull(Object root, String... attributes) throws NoSuchFieldException, IllegalAccessException {
Object currentAttribute = root;
for(int attr = 0; currentAttribute != null && attr < attributes.length; attr++){
Field nextField = currentAttribute.getClass().getField(attributes[attr]);
Object nextAttribute = nextField.get(current);
if(nextAttribute == null) return false;
currentAttribute = nextAttribute;
}
return true;
}
How to use it: if(checkDeepNull(bundle, "category", "subcategory", "item"))
You could have an interface which determines nullability:
public interface Nullability {
public boolean hasNulls();
}
And then simply have the parent call any children like so:
public boolean hasNulls() {
return this.bundle == null || bundle.hasNulls();
}
//in bundle
public boolean hasNulls() {
return this.category == null || category.hasNulls();
}
Regardless, if you have to nullcheck everything, you're going to be doing a lot of boilerplate code if you don't provide a means of iteration. That's what you should really focus on.
On a personal level, I disagree heavily with exposing fields like that. It's a very easy way to lead to more headaches and errors in design.
The short answer is no.
Can you redesign bundle so that it is always fully constructed? I.e., if bundle != null, then category, subcategory and item always exist? This could also help with concurrency issues. Basically, if nulls give you problems, where possible, don't allow these fields to be null.
Another option is the Null Object Pattern. Basically, you have a "default" implementation of Bundle which always return getCategory() that always returns a value for getSubcategory(), but ultimately the call to getItem() returns null or something to indicate "nothing". This is a great pattern but requires some work.
I hesitate to suggest it, but it is rare for any of the items to be null, at some point it may be faster and clearer to just catch the NPE, but this style should really be avoided. And it is a definite code smell that your design is poor. Avoid it if at all possible.
try {
return foo.bar.bap.zaz.blah.blah;
}
catch (NullPointerException ignored) {
return null;
}

Loop All button text in form [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I'm trying to do a loop thru all the button text in a form, but i can't find any solution for Java !!
i did something like :
for(JButton temp : this)
{
if(JButton.getText() == "A")
{
JButton.enabled(false);
}
}
but no luck
p.s. my problem is not about the equals statement !! I want to loop thru all button in my window.
here is the working result thanks to MadProgrammer:
for(Component comp : jPanel2.getComponents())
{
if(comp instanceof JButton)
{
JButton btn = (JButton)comp;
if(btn.getText().equals("A"))
{
btn.setEnabled(false);
}
}
}
You have a number of problems...
for(JButton temp : this) simply doesn't make sense, unless this implements Iterable<JButton>
if(JButton.getText() == "A") has two issues. The first is, getText() isn't a static method, so it can't be called in this manner, the second is, == shouldn't be used to compare String values...
JButton.enabled(false); has two issues. The first is, enabled isn't static and enabled is actually depreciated, so you should avoid using it. Instead using setEnabled
Without know how you buttons are actually managed, it's impossible to provide you an accurate solution.
If you are trying to iterate through the buttons on a Container of some kind, you might use something like...
for (Component comp : container.getComponents()) {
if (comp instanceof JButton) {
//...
}
}
For example.
If the buttons are stored in some kind of java.util.List, you could using something like...
for (JButton button : listOfButtons) {
//...
}
In order to check the button text, you should use something like (using the previous example as a base)...
if ("A".equals(button.getText()) {...}
Take a look at Creating a GUI with Swing for more details
Take a look String compare
if("A".equals(temp.getText())) // or use if("A".equalsIgnoreCase(temp.getText()))
{
temp.setEnabled(false);
}
instead of
if(JButton.getText() == "A")
{
JButton.enabled(false);
}
The problem with your code is == sign. Whenever you compare the values of two objects, here being String, you use the equals() method instead of ==.
The operator == is for primitive types. In case of objects, it will compare the addresses instead of the object's value. On the other hand, equals() will actually compare the values.
Try:
for(JButton temp : listOfButtons) // I changed the iterable here.
{
if("A".equals(temp.getText())) // notice who the caller to .equals() is. It is "A"
{
temp.setEnabled(false); // make temp disabled
}
}
Not being harsh but the code that you were using was completely flawed. I corrected the errors; see if that works for you.
The errors were: 1. Your source of buttons in the for loop was wrong. 2. getText() was used as a static method while it is dynamic. 3. You used an == instead of equals() 4. setEnabled() was used as a static method instead of dynamic

Categories