Type of iterator erroneous - java

I am working on a project in java and I am developing a API for custom components. I am using an interface called DrawHandler to allow the components to draw to a graphics object. To do this every time a component is added I need to add it's DrawHandlers to a list. I am using this code
public void addComponent(Component c){
//Add to list of components
components.add(c);
//Add all of the components drawHandlers so the component can be drawn
List<DrawHandler> dhs = c.getDrawHandlers();
Iterator<DrawHandler> i = dhs.iterator();
while(i.hasNext()){
addDrawHandler(i.next());
}
}
However when I get an error on this line
Iterator<DrawHandler> i = dhs.iterator();
and this line
addDrawHandler(i.next())
The error is:
The type of next() is erroneous : where E is a type-variable:
E extends Object declared in interface Iterator
If I use this code as sugested
public void addComponent(Component c){
//Add to list of components
components.add(c);
//Add all of the components drawHandlers so the component can be drawn
for(DrawHandler handler : c.getDrawHandlers())
addDrawHandler(handler);
}
I get this error when i compile it :
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - Erroneous tree type: windows.DrawHandler
at windows.MainWin.addComponent(MainWin.java:37)
at windows.Main.main(MazeNavigator.java:21)
Any sugjestions? What am I doing wrong? thanks for your your help

It doesn't explain your error but you may find it compiles fine if you write
for(DrawHandler handler : c.getDrawHandlers())
addDrawHandler(handler);
Uncompilable source code - Erroneous tree type: windows.DrawHandler
This means you are using an option which allows you to run code which doesn't compile. I suggest you turn this option off and you should see the true cause of your error.

Related

ClassCastException in JavaFX

My code gets the following error.
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: javafx.scene.Group cannot be cast to javafx.scene.control.TreeCell
Source code
private TreeItem getClickedTreeItem(EventTarget eventTarget){
TreeItem clickedTreeItem = null;
if(eventTarget instanceof TreeCellSkin){
clickedTreeItem = (TreeItem) ((TreeCell) ((TreeCellSkin)eventTarget).getParent()).getTreeItem();
}else if(eventTarget instanceof LabeledText){
clickedTreeItem = (TreeItem) ((TreeCell) ((LabeledText)eventTarget).getParent().getParent()).getTreeItem();
}else if(eventTarget instanceof ImageView){
clickedTreeItem = (TreeItem) ((TreeCell) ((ImageView)eventTarget).getParent().getParent()).getTreeItem();
}
return clickedTreeItem;
}
The console says this line:
clickedTreeItem = (TreeItem) ((TreeCell) ((ImageView)eventTarget).getParent().getParent()).getTreeItem();
This is legacy code that worked with Java 6, but gives the above exception using Java8?
What could be causing the ClassCastException now, and how to fix it for Java8?
The current code is brittle as it relies on the internal structure of the TreeCell. Also, TreeCellSkin1 and LabeledText are both internal classes. Internal code is subject to change without notice and without regards to third party reliance on it. Since this worked in Java 6 but not Java 8 I can only assume that the ImageView's grandparent changed from being the TreeCell to being a Group between the two versions.
To fix this you could look into the implementation and see what you need to do so you reach the TreeCell again, but that wouldn't really solve the problem. The use of EventTarget says to me this code was implemented while not fully understanding how event handling works in JavaFX. From the apparent goal of this code you should be using the source of the event, not the target. In JavaFX, the source of the event is always the object for which the EventHandler currently handling said Event was added to2. In other words, if you added the EventHandler to the TreeCell then the source will be the TreeCell. Using the source, and assuming EventHandler is added to the TreeCell, you can simply do:
TreeItem<?> item = ((TreeCell<?>) event.getSource()).getTreeItem();
Of course, if you're adding the EventHandler to the TreeCell you likely needn't bother with the source as you'll have access to the TreeCell directly. For example:
TreeView<String> treeView = new TreeView<>();
treeView.setCellFactory(tv -> {
TreeCell<String> cell = new TreeCell<>(); // or some custom implementation
cell.setOnMouseClicked(event -> {
TreeItem<String> item = cell.getTreeItem();
// do something with item...
});
return cell;
});
1. TreeCellSkin became public API in JavaFX 9 along with many (all?) skin implementations. They are part of the javafx.scene.control.skin package.
2. There's more to it but that's beyond the scope of this answer.

InvalidStackFrameException After Calling Method via ObjectReference#invokeMethod

I am currently working on an Eclipse plugin which enhances the debugging possibilities. During the debugging session, I invoke a Scala method via com.sun.jdi.ObjectReference#invokeMethod like that:
public int callMethod_Reactive_Level(final ObjectReference o) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException {
final Method m = apiValues.getMethod_Reactive_level(o); // com.sun.jdi.Method
final IntegerValue intVal = (IntegerValue) o.invokeMethod(thread, m, new LinkedList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);
return intVal.intValue();
}
After doing that, a call to org.eclipse.debug.core.model.IVariable#getValue leads to an InvalidStackFrameException. The whole error message is:
Status ERROR: org.scala-ide.sdt.debug code=5010 Exception while retrieving variable's value com.sun.jdi.InvalidStackFrameException
The message Exception while retrieving variable's value is shown when I inspect a variable in the variables view after calling a method as shown above.
Any idea how this problem can be solved? I do not understand why this is so problematic, since the JDI explicitely provides the possibility to do that.
Update: Since it may be a bug in the Scala IDE, there is a discussion and a tutorial how to reproduce the issue in the Scala IDE dev group.
The error message seems to come from the Scala IDE implementation of IVariable.getValue. It delegates to the JDI StackFrame.getValue, which throws. According to the docs, this can happen "if this stack frame has become invalid. Once the frame's thread is resumed, the stack frame is no longer valid."
My guess is that executing an invokeMethod on the same thread invalidates the stack frame.

Importing StaggeredGridView library - Parcel.CreateIntArry() not applicable for Parcel.CreateIntArry(int[]) error

I've been trying to import StaggeredGridView library in to eclipse. Everything works fine except an error in the StaggeredGridView.java.
In the following method of the class
private SavedState(Parcel in) {
super(in);
firstId = in.readLong();
position = in.readInt();
in.createIntArray(topOffsets); //error here
in.readTypedList(mapping, ColMap.CREATOR);
}
eclipse shows the error
The method createIntArray() in the type Parcel is not applicable for
the arguments (int[])
Any suggestions how to get rid of this error?
The error is showing because the Parcel class does not define a createIntArray(int[]) method that takes a parameter. There are two options:
createIntArray() (without parameter)
readIntArray(int[])
Based on the commit that's now causing the compile error, it used to be readIntArray(int[]). I'm not sure why it was changed in the first place, but it seems to be related to the StaggeredGridView not always being restored properly. For the time being, you may just want to change it back to how it was before, and keep an eye out for any new commits to the git repo.

JEditorPane - setText from ArrayList<String> contents?

I have read through the JEditorPane Docs, from what I can understand you simply need to editorpane.setText(String value); however I am quite new to java and this solution does not work with my code. I think I am missing something obvious but completely out of ideas.
I have created a new tab with this class that extends JEditorPane, this class is designed to open the contents of the file, put them on an array, reverse the array (so latest entry is on the top) then display this list in the JEditorPane (using JeditorPane because I need to make the save url's into hyperlinks),
public class HistoryPane extends JEditorPane{
ArrayList<String> historyToSort = new ArrayList<String>();
public HistoryPane(){
setEditable(false);
historySort();
}
public void historySort() {
try (BufferedReader reader = new BufferedReader(new FileReader("BrowserHistory.txt")))
{
String currentLine;
String newLine = new String("\n");
while ((currentLine = reader.readLine()) != null) {
historyToSort.add(currentLine + newLine);
}
} catch (IOException e) {
e.printStackTrace();
}
Collections.reverse(historyToSort);
System.out.println(historyToSort);
}
{
}
private void displayHistory(){
String sorted = historyToSort.toString();
***** HistoryPane.setText(String sorted); <<<------ PROBLEM SYNTAX.*****
}
}
I have tried multiple different entries into the setText() parenthesis with no luck. What am I missing? Thank You.
NOTE:
This class won't compile because it is reliant on another class (I can't paste all of it) but this code sits within a tabbed pane created by my main class:
Error Message:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problems:
Syntax error on token "setText", Identifier expected after this token
Return type for the method is missing
This method requires a body instead of a semicolon
OK, despite the fact that you haven't read the error message, it seems you're really a newbie, so I'll help.
HistoryPane.setText(String sorted);
The above isn't valid Java. A method invocation takes a list of arguments, without a type.
HistoryPane.setText(sorted);
Now that is a valid method invocation. But it tries to invoke a static method called setText() of the class HistoryPane. What you want is to invoke the instance method setText() on the current object. So the valid syntax is
this.setText(sorted);
or simply
setText(sorted);
That should solve this particular compilation error. Don't try to run your app before every compilation error, listed in the Problems view of Eclipse, is fixed.
Note that the above line won't do what you want it to do, but I'll let you investigate what you should do instead.
My advice: don't try using Swing, which is quite a complex beast, if you don't even know how to call a method yet. Start with very simple Java exercises, not involving any GUI, until you're familiar with the Java syntax, and understand how to read, understand and fix basic compilation problems.

How do I create a List of generic arrays in Java?

I've written a class which accepts a generic type, and I'm trying to create an array list of generic arrays within it. I understand that Java can't create generic arrays, but I also know there are workarounds. Is there a way the below code can work, or am I barking up the wrong tree?
public class IterableContainer<T extends IterableItem> {
private T[] itemArray;
// how can i get this following line to work?
private List<T[]> items = new ArrayList<T[10]>();
public IterableContainer() {
... etc ...
Ignore past here - turns out it was an IDE issue.
Left in for continuity of questions and answers.
EDIT:
This also doesn't work:
private List<T[]> items = new ArrayList<T[]>();
with the error:
Syntax error on token ">", VariableDeclaratorId expected after this token
"... barking up the wrong tree..., use a List<List<T>>. Using raw arrays in Java is almost always a code smell, there is no reason not to use the proper collection classes.
It works just fine, you just can't use the T[10] declaration as the length of an array doesn't affect its type.
i.e.
... = new ArrayList<T[]>();
Not saying it's a great idea, but it should be possible with the same restrictions on generic arrays as always. Creating stuff to put in your list will give you a headache.
private List<T[]> items = new ArrayList<T[]>();
works fine in my machine
When you say "I'm developing for mobile devices" ....are you targeting j2me? There is no support for generics in j2metargetng
This is a valid declaration in java (according to spec) and compiles just fine with javac as others have commented.
public class IterableContainer<T extends IterableItem> {
private T[] itemArray;
private List<T[]> items = new ArrayList<T[]>();// valid
..........
}
I believe the error you are seeing is not emitted from Eclipse, possibly coming from an Android SDK configured in Eclipse. If you create a Java Project in Eclipse, this code should work just fine. If you use this in an Android Project in Eclipse, you are likely to run into this one. I had this error when running this code from an Android project :
# guarantee(_name_index != 0 && _signature_index != 0) failed: bad constant pool index for fieldDescriptor
Sounds like you are restricted in an Android project, unfortunately.
You have not defined T in this code.
If you are creating a generic class, you need to write:
public class <T extends IterableItem> IterableContainer...
The next problem in your code is that you are trying to initilize items of ArrayList during its construction. It is impossible. You should rather write:
private List<T[]> items = new ArrayList<T[]>();

Categories

Resources