showing error to get length of null array error for Image view - android-sqlite

my problem is when I run the code the app jumps out the application.I am using SQLITE Database using Recycler View I have two view control 1 is Textview and another is Image view.An application running on Textview but when I use Image view then the Android Studio it has the error: "java.lang.NullPointerException: Attempt to get length of null array"
Thanx in advance.
here is my Recycler_List_Item_Adapter2.java
#Override
public void onBindViewHolder(MyViewHolder_item holder, int position) {
Recycler_List_Item_Pojo2 recycler_title_pojo=arrayList.get(position);
holder.outImage=recycler_title_pojo.getImg();
ByteArrayInputStream imageStream = new ByteArrayInputStream(holder.outImage);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);
holder.imageView.setImageBitmap(theImage);
holder.textView.setText(recycler_title_pojo.getBr_title());
}
#Override
public int getItemCount() {
return arrayList.size();
}
public class MyViewHolder_item extends RecyclerView.ViewHolder {
TextView textView;
CircleImageView imageView;
byte[] outImage;
here is my Recycler_List_Item_Pojo2.java
public class Recycler_List_Item_Pojo2 {
byte[] img=null;
String br_title,bt_material,br_procedure,br_notice;
public Recycler_List_Item_Pojo2(byte[] img, String br_title) {
this.img = img;
this.br_title = br_title;
}
public byte[] getImg() {
return img;
}
public void setImg(byte[] img) {
this.img = img;
}
public String getBr_title() {
return br_title;
}
public void setBr_title(String br_title) {
this.br_title = br_title;
}
Here is my Sqlite Database code
Recycler_List_Item_Pojo2 product = null;
List<Recycler_List_Item_Pojo2> productList = new ArrayList<Recycler_List_Item_Pojo2>();
openDatabase();
Cursor cursor = mDatabase.rawQuery(" select * from a", null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
product = new Recycler_List_Item_Pojo2(cursor.getBlob(1),cursor.getString(2));
productList.add(product);
cursor.moveToNext();
}
cursor.close();
closeDatabase();
return productList;
Here is my error
FATAL EXCEPTION: main
Process: com.pp.receipe, PID: 21550
java.lang.NullPointerException: Attempt to get length of null array
at java.io.ByteArrayInputStream.<init>(ByteArrayInputStream.java:60)
at com.pp.receipe.adapter.Recycler_List_Item_Adapter2.onBindViewHolder(Recycler_List_Item_Adapter2.java:50)
at com.pp.receipe.adapter.Recycler_List_Item_Adapter2.onBindViewHolder(Recycler_List_Item_Adapter2.java:30)

#Prashant Please check your SQLITE Database.If any NULL value is inserted or check any field is empty or not.Remove your empty field from database.

Related

mybatis interceptor throw Reflection exception affects cpu performence

I had implement a interceptor of myabtis. but we found a problem, execute interceptor lead to throw so many IllegalAccessException, it affects cpu performence
Shown below is where the problem is, why did not check access permision of feild befor executed code "field.get(target)".
public class GetFieldInvoker implements Invoker {
private final Field field;
public GetFieldInvoker(Field field) {
this.field = field;
}
#Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException {
try {
return field.get(target);
} catch (IllegalAccessException e) {
if (Reflector.canControlMemberAccessible()) {
field.setAccessible(true);
return field.get(target);
} else {
throw e;
}
}
}
#Override
public Class<?> getType() {
return field.getType();
}
}
the intercepor of mine:
#Intercepts({
#Signature(
type = StatementHandler.class,
method = "prepare",
args = {Connection.class, Integer.class})
})
public class SqlIdInterceptor implements Interceptor {
private static final int MAX_LEN = 256;
private final RoomboxLogger logger = RoomboxLogManager.getLogger();
#Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = realTarget(invocation.getTarget());
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
String originalSql = boundSql.getSql();
MappedStatement mappedStatement =
(MappedStatement) metaObject.getValue("delegate.mappedStatement");
String id = mappedStatement.getId();
if (id != null) {
int len = id.length();
if (len > MAX_LEN) {
logger.warn("too long id", "id", id, "len", len);
}
}
String newSQL = "# " + id + "\n" + originalSql;
metaObject.setValue("delegate.boundSql.sql", newSQL);
return invocation.proceed();
}
#SuppressWarnings("unchecked")
public static <T> T realTarget(Object target) {
if (Proxy.isProxyClass(target.getClass())) {
MetaObject metaObject = SystemMetaObject.forObject(target);
return realTarget(metaObject.getValue("h.target"));
}
return (T) target;
}
}
Flame Graph
enter image description here
enter image description here
I need help, how to avoid throw exceptions, is any other way to reslove this problem?
thanks.

How to fix " java.lang.IllegalStateException: Couldn't read row 2, col 7 from CursorWindow."

When I insert the database from SQLite into Music Adapter using CursorWindow, it will report an error
"java.lang.IllegalStateException: Couldn't read row 0, col 7 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it."
This is for Android Studio 3.3. In the past, I've tried on Inserting and exporting data from SQlite to ArrayAdapter for Listview and errors often occur:
"java.lang.IllegalStateException: Couldn't read row 0, col 7 from CursorWindow"
This is my code:
public class MusicAdapter extends ArrayAdapter<Music>
{
Activity context;
int resource;
List<Music> objects;
int Like =0;
public MusicAdapter(Activity context, int resource, List<Music> objects)
{
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.objects = objects;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = this.context.getLayoutInflater();
View row = inflater.inflate(this.resource,null);
TextView txtMa = row.<TextView>findViewById(R.id.txtMa);
TextView txtTen = row.<TextView>findViewById(R.id.txtTen);
TextView txtCaSi = row.<TextView>findViewById(R.id.txtCaSi);
final TextView txtLike = row.<TextView>findViewById(R.id.txtLike); final TextView txtDisLike = row.<TextView>findViewById(R.id.txtDisLike);
ImageButton btnLike = row.<ImageButton>findViewById(R.id.btnLike);
ImageButton btnDisLike = row.<ImageButton>findViewById(R.id.btnDisLike);
final Music music = this.objects.get(position);
txtTen.setText(music.getTen());
txtMa.setText(music.getMa());
txtCaSi.setText(music.getCaSi());
btnLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
xuLyThich(music, position,txtLike);
}
});
btnDisLike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
xuLyKhongThich(music,position,txtDisLike);
}
});
return row;
}
private void xuLyKhongThich(Music music, int pos,TextView txtDisLike)
{
int no_un_like =0;
Cursor cursor=MainActivity.database.query("ArirangSongList",null,
null,null,
null,null,null);
try {
if (cursor!= null) {
cursor.move(pos+1);
no_un_like = cursor.getInt(8);
Log.d("no_unlike",String.valueOf(no_un_like));
}
} finally {
cursor.close();
}
ContentValues row = new ContentValues();
row.put("Dislike", no_un_like+1);
try{
MainActivity.database.update("ArirangSongList", row, "MABH= ?", new String[]{String.valueOf(music.getMa())});
txtDisLike.setText(String.valueOf(no_un_like+1));
}finally {
}
}
private void xuLyThich(Music music, int pos,TextView txtlike)
{
int no_like =0;
Cursor cursor=MainActivity.database.query("ArirangSongList",null,
null,null,
null,null,null);
try {
if (cursor!= null) {
cursor.move(pos+1);
no_like = cursor.getInt(7);
Log.d("no_like",String.valueOf(no_like));
}
} finally {
cursor.close();
}
ContentValues row = new ContentValues();
row.put("Like", no_like+1);
try{
MainActivity.database.update("ArirangSongList", row, "MABH= ?", new String[]{String.valueOf(music.getMa())});
txtlike.setText(String.valueOf(no_like+1));
}finally {
}
}
}
And this is my error:
java.lang.IllegalStateException: Couldn't read row 2, col 7 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(Native Method)
at android.database.CursorWindow.getLong(CursorWindow.java:507)
at android.database.CursorWindow.getInt(CursorWindow.java:574)
at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:69)
at muitenvang.adapter.MusicAdapter.xuLyThich(MusicAdapter.java:136)
at muitenvang.adapter.MusicAdapter.access$000(MusicAdapter.java:23)
at muitenvang.adapter.MusicAdapter$1.onClick(MusicAdapter.java:74)
at android.view.View.performClick(View.java:4204)
at android.view.View$PerformClick.run(View.java:17355)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
You issue is that your are trying to read a row from the Cursor that doesn't exist.
This is due to the position in the list not being an offset but being the sequential number. That is the first position is 1 whilst the equivalent row in the cursor would be 0 (position 2 would correlate with row 1 and so on).
Adding 1 to the position as per cursor.move(pos+1); makes the exception more likely to occur as does not checking the result of the move (false if the move could not be made else true) to see if the move succeeded.
Checking a Cursor, returned from an SQLiteDatabase method, such as query fir null, is useless as the Cursor will not be null. The Cursor would, if there are no rows, still be valid but the count, as could be checked with the Cursor getCount method would return 0 (or the number of rows in the Cursor).
Although not ideal changing :-
if (cursor!= null) {
cursor.move(pos+1);
no_like = cursor.getInt(7);
Log.d("no_like",String.valueOf(no_like));
}
To :-
if (cursor.move(pos-1) {
no_like = cursor.getInt(7);
Log.d("no_like",String.valueOf(no_like));
} else {
Log.d("no_like","Ooops could not move to row + String.valueOf(pos));
}
Would be more likely to work.
Note the same changes should be applied to xuLyKhongThich

I need to show different tool tip for each table cell

Please see this
This is what I want to see... I mean the tool tip
At run time I get this error message for each row that is being loaded.
The tool tip text lies in the an object and is retrieved by thisRow.getCourseTootip(i);
Number of columns in the table varies and I create them and add them to the table view thru code.
for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
thisColumn.setPrefWidth(80);
thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
String str = TableRows.get(1).getGrade(courseNo);
final int i = courseNo;
thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(i));
thisColumn.setCellFactory(new Callback<TableColumn<AResultRow, String>, TableCell<AResultRow, String>>() {
public TableCell<AResultRow, String> call(TableColumn<AResultRow, String> column) {
return new TableCell<AResultRow, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setText(item);
AResultRow thisRow = new AResultRow();
thisRow = getTableView().getItems().get(getTableRow().getIndex());
final Tooltip tip= new Tooltip();
tip.setText(thisRow.getCourseTootip(i));
setTooltip(tip);
tip.setStyle("-fx-background-color: pink; -fx-text-fill: black; -fx-font: normal normal 12pt \"Times New Roman\"");
}
}
};
}
});
boolean retVal = thisTable.getColumns().addAll(thisColumn);
}
Error is
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at victoriairene.TheMainFXMLController$1$1.updateItem(TheMainFXMLController.java:434)
at victoriairene.TheMainFXMLController$1$1.updateItem(TheMainFXMLController.java:427)
Line 434 is
thisRow = getTableView().getItems().get(getTableRow().getIndex());
Text for the tool tip for this cell comes from thisRow.getCourseTootip(i).
Can someone tell me, what is wrong with my code? Which object is null ? If it is null, then how do I get to see the correct Tooltip text, in spite of getting error messages for each row ?
I have been struggling with this for one full day.
Please help and thanks in advance.
As requested by Kleopatra I am enclosing the entire Create Table function.
public void createTableForThisSemester(int thisSemester, int numberOfCourses, javafx.collections.ObservableList<AResultRow> TableRows) {
TableView<AResultRow> thisTable = new TableView<>();
thisTable.setContextMenu(contextMenu);
TableColumn<AResultRow, String> tcolRollNo = new TableColumn<>("Roll Number");
tcolRollNo.setEditable(false);
tcolRollNo.setPrefWidth(120);
TableColumn<AResultRow, String> tcolName = new TableColumn<>("Student Name");
tcolName.setEditable(false);
tcolName.setPrefWidth(350);
tcolRollNo.setCellValueFactory(cellData -> cellData.getValue().StudentIDProperty());
tcolName.setCellValueFactory(cellData -> cellData.getValue().StudentNameProperty());
boolean xyz = thisTable.getColumns().addAll(tcolRollNo, tcolName);
// TableColumn[] courseColumn = new TableColumn[numberOfCourses];
for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
thisColumn.setPrefWidth(80);
thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
String str = TableRows.get(1).getGrade(courseNo);
final int i = courseNo;
thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(i));
thisColumn.setCellFactory(new Callback<TableColumn<AResultRow, String>, TableCell<AResultRow, String>>() {
public TableCell<AResultRow, String> call(TableColumn<AResultRow, String> column) {
return new TableCell<AResultRow, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setText(item);
AResultRow thisRow = new AResultRow();
thisRow = getTableView().getItems().get(getTableRow().getIndex());
final Tooltip tip= new Tooltip();
tip.setText(thisRow.getCourseTootip(i));
setTooltip(tip);
tip.setStyle("-fx-background-color: pink; -fx-text-fill: black; -fx-font: normal normal 12pt \"Times New Roman\"");
}
}
};
}
});
boolean retVal = thisTable.getColumns().addAll(thisColumn);
}
// System.out.println("# of Rows in Table [" + thisSemester + "] = " + TableRows.size());
TableColumn<AResultRow, String> tcolGPA = new TableColumn<>("GPA");
tcolGPA.setEditable(false);
tcolGPA.setPrefWidth(80);
tcolGPA.setStyle("-fx-alignment: CENTER; font-weight:bold;");
tcolGPA.setCellValueFactory(cellData -> cellData.getValue().returnStringGPA());
boolean retVal = thisTable.getColumns().addAll(tcolGPA);
thisTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
thisTable.setItems(TableRows);
thisTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
//Check whether item is selected and set value of selected item to Label
if (thisTable.getSelectionModel().getSelectedItem() == null) {
gRollNumber = null;
gStudentName = null;
} else {
gRollNumber = newValue.getStudentID();
gStudentName = newValue.getStudentName();
}
});
ScrollPane thisScrollPane = new ScrollPane();
thisScrollPane.setFitToWidth(true);
thisScrollPane.setFitToHeight(true);
thisScrollPane.setMinHeight((theDetails.getHeight() - 25));
thisScrollPane.setMaxHeight((theDetails.getHeight() - 25));
thisScrollPane.setMinWidth((theDetails.getWidth() - 25));
thisScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
Tab thisTab = tabs.getTabs().get(thisSemester);
thisTab.setContent(thisScrollPane);
thisScrollPane.setContent(thisTable);
}
I am repeating the hierarchy again - please excuse.
Table view is associated with an observablelist named ATableRows which a class ATableRow.
ATableRow contains several members and one of them is an array of class ACourseResult.
I need to know the ROW number and the array index (which is actually the Table Column number for that Cell) before I can retrieve the text for the tooltip.
Thing is the code works... except for the runtime error of null pointer. I still do not understand what the CellFactory and CellValueFactories do. Sorry about that. Oracle's documents do not say what they do......
While I am at this.... I want to tell you that my TABLE is READ ONLY. Do I Have to use the Observable List ? Can't I do this by setting values directly to each cell (just a curiosity).
Thanks in advance and sorry if my questions seem dumber.
Thanks to JAMES my problem is solved.... I am enclosing the modified code for others.
for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
thisColumn.setPrefWidth(80);
thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
String str = TableRows.get(1).getGrade(courseNo);
final int i = courseNo;
thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(i));
thisColumn.setCellFactory(new Callback<TableColumn<AResultRow, String>, TableCell<AResultRow, String>>() {
public TableCell<AResultRow, String> call(TableColumn<AResultRow, String> column) {
return new TableCell<AResultRow, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setText(item);
AResultRow thisRow = new AResultRow();
final int k = this.getIndex(); **// These are the changes suggested by James**
thisRow = getTableView().getItems().get(k); ***// These are the changes suggested by James***
// thisRow = getTableView().getItems().get(getTableRow().getIndex()); <- this is the old code commented out.
final Tooltip tip= new Tooltip();
tip.setText(thisRow.getCourseTootip(i));
setTooltip(tip);
tip.setStyle("-fx-background-color: pink; -fx-text-fill: black; -fx-font: normal normal 12pt \"Times New Roman\"");
}
}
};
}
});
boolean retVal = thisTable.getColumns().addAll(thisColumn);
}
The quick, and wrong, answer to the question is to point out that TableCell has a getTableRow() method, that will give you the row data without having to look it up through the underlying data via the row index.
Technically, you should give the TableCell all of the information it needs to work independently when its updateItem() method is called. This would mean restructing the data model such that the table cell is given a structure with both the displayed contents of the cell, and the text to go in the tooltip. It would appear that the AResultRow data structure has two associated lists, one with whatever shows in the cell, and the other with whatever goes into the tooltip. My suggestion would be to refactor that so that it's a single list holding objects which contain both data elements. Once you do that, the rest of the table structure becomes trivial. Here's a working example:
public class SampleTable extends Application {
private BorderPane testPane;
class TestPane extends BorderPane {
public TestPane(List<DataModel> dataItems) {
TableView<DataModel> tableView = new TableView<DataModel>();
setCenter(tableView);
TableColumn<DataModel, ClassInfo> column1 = new TableColumn<DataModel, ClassInfo>("column 1");
TableColumn<DataModel, ClassInfo> column2 = new TableColumn<DataModel, ClassInfo>("column 2");
column1.setCellValueFactory(new PropertyValueFactory<DataModel, ClassInfo>("column1Data"));
column2.setCellValueFactory(new PropertyValueFactory<DataModel, ClassInfo>("column2Data"));
column1.setCellFactory(column -> new CustomTableCell());
column2.setCellFactory(column -> new CustomTableCell());
tableView.getColumns().addAll(column1, column2);
tableView.setItems(FXCollections.observableList(dataItems));
}
}
public static void main(String[] args) {
launch(args);
}
public class CustomTableCell extends TableCell<DataModel, ClassInfo> {
#Override
protected void updateItem(ClassInfo item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
if (item != null) {
setText(item.getName());
setTooltip(new Tooltip(item.getDescription()));
}
}
}
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Task Progress Tester");
List<DataModel> dataItems = new ArrayList<DataModel>();
DataModel row1Data = new DataModel();
row1Data.setColumn1Data(new ClassInfo("row1Col1Name", "This is the description for Row1, Column 1"));
row1Data.setColumn2Data(new ClassInfo("row1Col2Name", "This is the description for Row1, Column 2"));
dataItems.add(row1Data);
DataModel row2Data = new DataModel();
row2Data.setColumn1Data(new ClassInfo("row2Col1Name", "This is the description for Row2, Column 1"));
row2Data.setColumn2Data(new ClassInfo("row2Col2Name", "This is the description for Row2, Column 2"));
dataItems.add(row2Data);
testPane = new TestPane(dataItems);
primaryStage.setScene(new Scene(testPane, 300, 250));
primaryStage.show();
}
public class DataModel {
private ObjectProperty<ClassInfo> column1Data = new SimpleObjectProperty<ClassInfo>();
private ObjectProperty<ClassInfo> column2Data = new SimpleObjectProperty<ClassInfo>();
public void setColumn2Data(ClassInfo newValue) {
column2Data.set(newValue);
}
public void setColumn1Data(ClassInfo newValue) {
column1Data.set(newValue);
}
public ObjectProperty<ClassInfo> column1DataProperty() {
return column1Data;
}
}
public class ClassInfo {
private String name;
private String description;
public ClassInfo(String name, String description) {
this.setName(name);
this.setDescription(description);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
}

DataFlavor in JavaFX not recognized correctly

I'm experiencing a problem when D&D a custom object from Swing to JavaFX and I'm wondering if I'm doing something wrong or its probably a Java FX bug.
My Transferable has been defined as the following:
public class TransferableEmployee implements Transferable {
public static final DataFlavor EMPLOYEE_FLAVOR = new DataFlavor(Employee[].class, "Employee");
public static final DataFlavor DEFINITION_FLAVOR = new DataFlavor(PropertyDefinition[].class, "Definition");
private static final DataFlavor FFLAVORS [] = {EMPLOYEE_FLAVOR, DEFINITION_FLAVOR};
private Employee[] employees;
private PropertyDefinition[] propertyDefinitions;
public MintTransferableEmployee(Employee[] employees, PropertyDefinition[] propertyDefinitions) {
this.employees = employees != null ? employees.clone() : null;
this.propertyDefinitions = propertyDefinitions != null ? propertyDefinitions.clone() : null;
}
public DataFlavor[] getTransferDataFlavors() {
return FFLAVORS.clone();
}
public Object getTransferData(DataFlavor aFlavor) throws UnsupportedFlavorException {
Object returnObject = null;
if (aFlavor.equals(EMPLOYEE_FLAVOR)) {
returnObject = employees;
}
else if(aFlavor.equals(DEFINITION_FLAVOR)){
returnObject = propertyDefinitions;
}
else{
throw new UnsupportedFlavorException(aFlavor);
}
return returnObject;
}
public boolean isDataFlavorSupported(DataFlavor aFlavor) {
boolean lReturnValue = false;
for (int i=0, n=FFLAVORS.length; i<n; i++) {
if (aFlavor.equals(FFLAVORS[i])) {
lReturnValue = true;
break;
}
}
return lReturnValue;
}
}
I've created an imageView (FX Component) where I added the setOnDragOver just as the following:
employeePhotoImageView.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
System.out.println("dragOver");
event.getDragboard().getContentTypes();
event.getDragboard().getContent(DataFormat.lookupMimeType("application/x-java-serialized-object"));
}
});
The getContentTypes() returns a Map with [[application/x-java-serialized-object]], so now I try to get the Content, and this only returns the List of PropertyDefinition but no Employee at all (which in this case, is the one I need).
If I remove the data of the PropertyDefinition in the transferable, the employee is returned in the getContent(DataFormat) method.
For me, this means that JavaFX only works with 1 DataFlavor or somehow it is only returning the last flavor found in the Transferable.
Any clues on this?
Thanks in advanced...

Drag and drop to other applications and OS?

I'm using JavaFX's Drag and Drop system in my application, and it has been working well so far.
Now I want to support drag and drop to outside applications, eg. dragging files from my application to the explorer. How would I achieve that?
I've achieved what you described by using:
Vector<File> files = new Vector<File>();
private ClipboardContent filesToCopyClipboard = new ClipboardContent();
...
final ObjectWithAReturnablePathField draggableObj = new ObjectWithAReturnablePathField();
...
draggableObj.setOnDragDetected(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent me)
{
Dragboard db = draggableObj.startDragAndDrop(TransferMode.ANY);
try
{
File f = new File(new URI(draggableObj.getFilePath()));
files.add(f);
filesToCopyClipboard.putFiles(files);
}
catch (URISyntaxException e)
{
e.printStackTrace();
}
db.setContent(filesToCopyClipboard);
me.consume();
}
});
draggableObj.setOnDragDone(new EventHandler<DragEvent>()
{
#Override
public void handle(DragEvent me)
{
me.consume();
}
});
Which means:
It's possible to achieve file transference between JavaFX 2 and a native application by filling a ClipboardContent with a list using the TransferMode.ANY on the setOnDragDetected method of any Draggable Object (Any Node) which can return a Path for a file. In my case, I've created a class called Thumb extending ImageView and (among others things) I made a method called getFilePath() which returns the Path from the Image used to initialize the ImageView(). I'm sorry BTW for the poor example and the poor english, but I'm running out of time to give a more detailed answer as of now. I hope it helps. Cheers
Here is a sample source for an action listener on an ImageView image extraction to OS' explorer (With a custom process for jpg image to remove alpha-channel to display it correctly):
inputImageView.setOnDragDetected(new EventHandler <MouseEvent>() {
#Override
public void handle(MouseEvent event) {
// for paste as file, e.g. in Windows Explorer
try {
Clipboard clipboard Clipboard.getSystemClipboard();
Dragboard db = inputImageView.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
Image sourceImage = inputImageView.getImage();
ImageInfo imageInfo = (ImageInfo) inputImageView.getUserData();
String name = FilenameUtils.getBaseName(imageInfo.getName());
String ext = FilenameUtils.getExtension(imageInfo.getName());
///Avoid get "prefix lenght too short" error when file name lenght <= 3
if (name.length() < 4){
name = name+Long.toHexString(Double.doubleToLongBits(Math.random()));;
}
File temp = File.createTempFile(name, "."+ext);
if (ext.contentEquals("jpg")|| ext.contentEquals("jpeg")){
BufferedImage image = SwingFXUtils.fromFXImage(sourceImage, null); // Get buffered image.
BufferedImage imageRGB = new BufferedImage(image.getWidth(),image.getHeight(),
BufferedImage.OPAQUE);
Graphics2D graphics = imageRGB.createGraphics();
graphics.drawImage(image, 0, 0, null);
ImageIO.write(imageRGB, ext, temp);
graphics.dispose();
ImageIO.write(imageRGB,
ext, temp);
}else{
ImageIO.write(SwingFXUtils.fromFXImage(sourceImage, null),
ext, temp);
}
content.putFiles(java.util.Collections.singletonList(temp));
db.setContent(content);
clipboard.setContent(content);
event.consume();
temp.deleteOnExit();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
});
With the help of use of an Object that is passed to the imageView's setUserData method, it helps me to retrieve database id and pic name:
public class ImageInfo {
private String imageInfo;
private int inputId;
#Override
public String toString() {
return imageInfo;
}
public ImageInfo(String imageInfo, int inputId) {
this.imageInfo = imageInfo;
this.inputId = inputId;
}
public String getName() {
return imageInfo;
}
public void setName(String imageInfo) {
this.imageInfo = imageInfo;
}
public int getIndex() {
return inputId;
}
public void setIndex(int areaindex) {
this.inputId = inputId;
}
}
I hope it will help somenone at an expected time :-)
Regards