getting corresponding filename of image once button pressed - java

A Set of imagefiles are added to an arraylist(filelist2) of type File.Then an imageview and a button are addded to a vbox,such vboxes are added to a grids of a gripane using a for loop.( number of iterations is equal to size of the filelist2)Once a button is pressed I need to get the corresponding filename of the image within that vbox.
Say I pressed the button contained at (1,1) {i.e row no01 ,col no1} I need to get filename of image at (1,1)
here's a screenshot:
here's my code: FXMLController
File file = new File("D:\\SERVER\\Server Content\\Apps\\icons");
File[] filelist1 = file.listFiles();
ArrayList<File> filelist2 = new ArrayList<>();
for (File file1 : filelist1) {
filelist2.add(file1);
}
btnar = new ArrayList<>();
for (int i = 0; i < filelist2.size(); i++) {
downloadbtn = new Button("Download");
btnar.add(downloadbtn);
final int index=i;
downloadbtn.setId(String.valueOf(index));
downloadbtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
try {
System.out.println("sssss");
downloadbtn.getId();
//System.out.println(filelist2.get(Integer.valueOf(downloadbtn.getId())).getName());
} catch (Exception ex) {
Logger.getLogger(HomeUI_2Controller.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
System.out.println(filelist2.size());
gridpane.setAlignment(Pos.CENTER);
gridpane.setPadding(new Insets(20, 20, 20, 20));
gridpane.setHgap(20);
gridpane.setVgap(20);
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setFillWidth(true);
columnConstraints.setHgrow(Priority.ALWAYS);
gridpane.getColumnConstraints().add(columnConstraints);
int imageCol = 0;
int imageRow = 0;
for (int i = 0; i < filelist2.size(); i++) {
System.out.println(filelist2.get(i).getName());
image = new Image(filelist2.get(i).toURI().toString());
pic = new ImageView();
pic.setFitWidth(130);
pic.setFitHeight(130);
pic.setImage(image);
vb = new VBox();
vb.getChildren().addAll(pic, (Button) btnar.get(i));
gridpane.add(vb, imageCol, imageRow);
GridPane.setMargin(pic, new Insets(2, 2, 2, 2));
imageCol++;
// To check if all the 3 images of a row are completed
if (imageCol > 2) {
// Reset Column
imageCol = 0;
// Next Row
imageRow++;
}
}

Why not simply
System.out.println(filelist2.get(index).getName());
?
(Actually, it's not really clear to me why you create filelist2 at all. Why not do
btnar = new ArrayList<>();
for (int i=0; i < filelist1.length; i++) {
downloadbtn = new Button("Download");
btnar.add(downloadbtn);
final int index=i;
downloadbtn.setId(String.valueOf(index));
downloadbtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
try {
System.out.println("sssss");
System.out.println(filelist1[index].getName());
} catch (Exception ex) {
Logger.getLogger(HomeUI_2Controller.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}

Use setUserData and getUserData to store and retrieve custom values in Nodes ! Set the fileName as the userdata and on click, retrieve it.
downloadbtn.setUserData(filelist2.get(index).getName());
downloadbtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
System.out.println(downloadbtn.getUserData());
}

Consider using a java.util.HashMap<Button, File> and calling hashMap.get(actionEvent.getSource()).getName() to get the file name.

I've created a DataButton which can hold some typed data (unlike userData which has the type Object).
You can specify a Renderer to render the data on the button or to render an alternative text, eg. in your case: "Download".
Eg. you could use something like this:
List<Path> pathlist2 = new ArrayList<>();
...
// provide language specific text for "Download"
ResourceBundle myResourceBundle = ...;
...
DownloadRenderer downloadRenderer = new DownloadRenderer(myResourceBundle);
...
// the dafault renderer would set the text property to path.toString()
DataButton<Path> downloadbtn = new DataButton<>(downloadRenderer);
downloadbtn.setData(pathlist2.get(index));
downloadbtn.setOnAction((actionEvent) -> {
Path path = downloadbtn.getData();
...
});
...
private static class DownloadRenderer extends AbstractDataRenderer<Object> {
private final ResourceBundle myResourceBundle;
public DownloadRenderer(final ResourceBundle myResourceBundle) {
this.myResourceBundle = myResourceBundle;
}
#Override
public String getText(Object item) {
return myResourceBundle.getString("downloadbtn.text");
}
}
As you can see, you can work directly with Path objects (which should be preferred to the legacy File objects). You don't have to cast or convert the data.
Note: you could also omit the DownloadRenderer and set the text property directly:
downloadbtn.setData(pathlist2.get(index));
downloadbtn.setText(myResourceBundle.getString("downloadbtn.text"));
But then you have to make sure to call setText always after setData.
The library is Open Source and is available from Maven Central:
<dependency>
<groupId>org.drombler.commons</groupId>
<artifactId>drombler-commons-fx-core</artifactId>
<version>0.4</version>
</dependency>

Related

How can be draw marker on linechart using MPAndroidChart:v3.1.0 in android?

I am using MPAndroidChart:v3.1.0 dependency . But I am not able to show marker every point of line chart.
Dependencies this: implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
I am using below listener
enter code here
'''
lineChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
#Override
public void onValueSelected(Entry e, Highlight h) {
IDataSet iDataSet = lineChart.getData().getDataSets().get(h.getDataSetIndex());
Highlight highlight[] = new Highlight[((LineDataSet) iDataSet).getValues().size()];
for (int i = 0; i < ((LineDataSet) iDataSet).getValues().size(); i++) {
Highlight highlight1 = new Highlight(e.getX(), e.getY(), h.getXPx(), h.getYPx(), h.getDataSetIndex(), h.getStackIndex(), h.getAxis());
highlight1.setDataIndex(i);
highlight[i] = highlight1;
}
MarkerView markerView = new CustomMarkerView(TestPerformanceActivity.this, R.layout.custom_markerview, R.color.red);
markerView.setChartView(lineChart);
lineChart.setMarker(markerView);
lineChart.setDrawMarkers(true);
lineChart.highlightValues(highlight);
lineChart.notifyDataSetChanged();
Log.e("LineChartSelection", "onValueSelected");
}
#Override
public void onNothingSelected() {
Log.e("LineChartSelection", "onNothingSelected");
}
});
'''
I am also call these method on LineDataSet
method is: lineDataSet.setHighlightEnabled(true);
lineDataSet.setDrawHighlightIndicators(true);
But I am not able show marker on line chart . For better reference check screenshot which I want to show.
enter image description here

Getting images to show on grid-pane dynamically

My goal is to display images that are selected from a filechooser activated by button, and add those images to my gridpane. I am able to get the right URL file path name from the file chooser in order to make a correct imageview however when doing so my gridpane does not show any images being added..
public void makeBrowseButton(Stage primaryStage) {
//attach handler
browseButton.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
FileChooser fileChooser = new FileChooser(); // create object
fileChooser.getExtensionFilters()
.addAll(new FileChooser.ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif")); //filter for music files
//FileFilter filter = new FileNameExtensionFilter("JPEG file", "jpg", "jpeg");
if (!parentPath.equalsIgnoreCase(
"")) { //go to previous directory if exists
File parentPathFile = new File(parentPath);
fileChooser.setInitialDirectory(parentPathFile);
}
File selectedFile = fileChooser.showOpenDialog(primaryStage);
if (selectedFile != null) { // display the dialog box
String wholePath = selectedFile.getPath();
String name = selectedFile.getName();
String megaPath = selectedFile.getAbsolutePath();
String megaUrl;
try {
megaUrl = Paths.get(megaPath).toUri().toURL().toString();
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
parentPath = selectedFile.getParent();
System.out.println("wholePath: " + wholePath);
System.out.println("parent: " + parentPath);
System.out.println("File Name: " + name);
System.out.println("megaPath: " + megaUrl);
//System.out.println("Canonical: " + Canonical);
Image newAwesomeImage = new Image(megaUrl);
paneofgridmonkeys.add(new ImageView(newAwesomeImage), 0, 0);
//ImageView view = new ImageView();
//view.setImage(newAwesomeImage);
//paneofgridmonkeys.add(view, 1, 1);
//paneofgridmonkeys.setConstraints(view, 0, 4);
//paneofgridmonkeys.add(new Label("Changed the image!"), 0, 1);
createDisplay(primaryStage);
}
}
});
}
I've tried multiple ways of insterting an images and these are the filepaths im getting:
wholePath: \\jupiter\yr1005\Desktop\20190111_1340501.jpg
parent: \\jupiter\yr1005\Desktop
File Name: 20190111_1340501.jpg
megaPath: file://jupiter/yr1005/Desktop/20190111_1340501.jpg
(im using the megapath)
basically when i choose an image from filechooser I get no error but no image is shown after selection. I just get all the print statements in return.. an idea why?
This is my create Display method:
public void createDisplay(Stage primaryStage) {
primaryStage.setTitle(this.MONKEY_TITLE);
GridPane paneofgridmonkeys = new GridPane();
paneofgridmonkeys.setAlignment(Pos.CENTER);
paneofgridmonkeys.setVgap(10);
paneofgridmonkeys.add(browseButton, 10, 10);
ScrollPane allTehFaces = new ScrollPane(paneofgridmonkeys);
allTehFaces.setFitToWidth(true);
primaryStage.setScene(new Scene(allTehFaces, 500, 500));primaryStage.show();
}
}
You're problem is in the createDisplay method; specifically this line:
GridPane paneofgridmonkeys = new GridPane();
Here you're creating a locally-scoped GridPane called paneofgridmonkeys, which must be the name of another class-level variable called paneofgridmonkeys, since it's available to makeBrowseButton. When you do this in local scope, the new instance you've created becomes the one that's used inside of that method, rather than the class-level instance; thus the class-level one isn't the one being added to your scene, and you're not seeing the changes.

JGraphX new initialization of graph/graphComponent does not work as expected and causes artefacts

Hi I am using JGraphX to build some kind of Java swing based graph editor application. The application in general works fine and as intended under normal
circumstances. In general I have an class called Editor which contains all essential declarations for the graph, as seen in the code example below.
initializing the graph and overriding some of its methods
public class Editor extends JFrame implements Serializable {
Handler handler;
JTabbedPane tabPane;
mxGraphComponent graphComponent;
EntityDataTable dataTable;
protected static mxGraph graph = new mxGraph() {
// Overrides method to disallow edge label editing
public boolean isCellEditable(Object cell) {
if (cell instanceof mxCell) {
mxCell c = (mxCell) cell;
if (c.isEdge()) {
return false;
} else {
return false;
}
}
return false;
}
// Overrides method to disallow edge selection
public boolean isCellSelectable(Object cell)
{
if (model.isEdge(cell))
{
return false;
}
return super.isCellSelectable(cell);
}
// Overrides method to provide a cell label in the display
public String convertValueToString(Object cell) {
if (cell instanceof mxCell) {
Object value = ((mxCell) cell).getValue();
if (value instanceof Element) {
Element elt = (Element) value;
// String tag = elt.getTagName();
String tag = elt.getAttribute("name");
return tag;
}
}
return super.convertValueToString(cell);
}
public String getToolTipForCell(Object cell){
return "Double Click to Edit";
}
};
...
restricts certain undoEvents
protected mxEventSource.mxIEventListener undoHandler = new mxEventSource.mxIEventListener(){
public void invoke(Object source, mxEventObject evt)
{
mxUndoableEdit evt1 = (mxUndoableEdit) evt.getProperty("edit");
List<mxUndoableEdit.mxUndoableChange> changes = evt1.getChanges();
Object[] temp = graph.getSelectionCellsForChanges(changes);
boolean islegal = true;
for (int i = 0; i < temp.length; i++)
{
mxCell cell = (mxCell)temp[i];
String value = cell.getValue().toString();
if (value.equals("subprocess")||value.equals("optional")||value.equals("parallel")||value.equals("synchronous")||value.equals("activating")||value.equals("deactivating")){
//System.out.println("is not legal");
islegal = false;
}
}
for (int i = 0; i < changes.size(); i++){
if (changes.get(i).toString().contains("mxValueChange")){
islegal = false;
}
}
graph.setSelectionCells(graph.getSelectionCellsForChanges(changes));
if (islegal == true){
undoManager.undoableEditHappened((mxUndoableEdit) evt
.getProperty("edit"));
}else{
// System.out.println("illegal undo");
}
}};
...
protected boolean modified = false;
protected mxGraphOutline graphOutline;
protected JPanel actionPane;
mxUndoManager undoManager;
public Editor() {
handler = new Handler(this);
dataTable = new EntityDataTable(handler);
initGUI();
initGraphSettings();
}
public Editor(SaveData saveData) {
handler = new Handler(this);
dataTable = new EntityDataTable(handler);
initGUI();
initGraphSettings();
//erst alle entities erstellen und submitten, dann alle verbindungselemente zu den entities hinzufügen und nochmal submit
//Load entities
ArrayList<DataSaveElement> saveDataList = saveData.getSaveData(); for (int i = 0; i < saveDataList.size(); i++){
System.out.println("Loaded "+saveDataList.get(i).getType()+" "+saveDataList.get(i).getName());
if (saveDataList.get(i).getType().equals("Process")){
ProcessPopUp temp = new ProcessPopUp(handler, this);
temp.setGlobalID(saveDataList.get(i).getGlobalID());
temp.setName(saveDataList.get(i).getName());
temp.setDesc(saveDataList.get(i).getDescription());
temp.setType(saveDataList.get(i).getType());
... a lot of code for rebuilding, some graph settings, the gui etc.
Inside of the initGui() my mxGraphComponent is initialized
graphComponent = new mxGraphComponent(graph);
Since the graph visualization is only one part of the application and other data exists in the background, while saving all data values are stored including the postions for vertices etc. So when loading a save file a fresh application is build from the ground up simply adding all saved data values step by step. When I close the entire java application, start it again and load my saved file there is no problem at all. The problem occures when loading a saved file while the application is still running like e. g.
menuItem = new JMenuItem("Open...",
new ImageIcon("images/middle.gif"));
menuItem.addActionListener(new ActionListener() {
#java.lang.Override
public void actionPerformed(ActionEvent e) {
LoadAndSaveManager manager = new LoadAndSaveManager();
try {
Object o = manager.load(new FileChooser(0).getSelectedFile().getAbsolutePath());
SaveData saveData =(SaveData) o;
Editor editorNew = new Editor(saveData);
new MenuBar(editorNew);
editorNew.setVisible(true);
editor.dispose();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
menu.add(menuItem);
My menubar is quite basic an gets the editor als parameter. Since a new Editor is created which creates a new mxGraph, as well as a new mxGraphComponent and finally disposes the old editor there should be no interference...at least as far as I know. However, despite having a new Editor instance which has its own new Graph and GraphComponent the old one is still used somehow. As shown in the example images below.
This will be saved and the application is closed completely.
Two nodes and a link for saving:
When starting the application and loading the saved data nothing is wrong.
Next I start a new one and add for example three nodes and two links.
Three nodes and two links:
Now I load the previously saved data. I would expect that the the window closes and a new one with the prevois data pops up. This is not the case. The data is loaded, but the old graph seems still active somehow and all nodes and links are on the graph.
Mixed up data:
If this would be the only problem I could simply clear the graph and add all "loading data" afterwards, however somehow the graphComponent seems to be broken as well. When dragging nodes the links sometimes are disrupted.
Disrupted links:
From my observations so far this seems to fix itself when selecting an area (I think this forces the graphComponent to refresh())
Selecting:
Unfortunately posting the entire code is not that much of an option, so I posted some code I think might be of importance for the problem. If further code is required I will specifically post it afterwards.
I am not sure why this happens and after hours of research I somehow hit a wall and and I am not sure what I am doing wrong. I would really appreciate some advice.
Here is an minimal full code example of the problem regarding the graphComponents interference problem when declaring a new one.
public class Main {
Editor editor;
public Main() {
editor = new Editor();
new MenuBar(editor);
editor.setVisible(true);
}
public static void main(String args[]) {
new Main();
}}
public class Editor extends JFrame {
mxGraphComponent graphComponent;
protected static mxGraph graph = new mxGraph() {
// Overrides method to disallow edge label editing
public boolean isCellEditable(Object cell) {
if (cell instanceof mxCell) {
mxCell c = (mxCell) cell;
if (c.isEdge()) {
return false;
} else {
return false;
}
}
return false;
}
// Overrides method to disallow edge selection
public boolean isCellSelectable(Object cell)
{
if (model.isEdge(cell))
{
return false;
}
return super.isCellSelectable(cell);
}
// Overrides method to provide a cell label in the display
public String convertValueToString(Object cell) {
if (cell instanceof mxCell) {
Object value = ((mxCell) cell).getValue();
if (value instanceof Element) {
Element elt = (Element) value;
// String tag = elt.getTagName();
String tag = elt.getAttribute("name");
return tag;
}
}
return super.convertValueToString(cell);
}
public String getToolTipForCell(Object cell){
return "Double Click to Edit";
}
};
public Editor() {
initGUI();
initGraphSettings();
}
public Editor(ArrayList<SaveDataElement> saveData) {
initGUI();
initGraphSettings();
//Load data
addToGraph(saveData);
}
public void initGUI(){
setExtendedState(JFrame.MAXIMIZED_BOTH);
setSize(new Dimension(1200, 900));
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
graphComponent = new mxGraphComponent(graph);
JPanel graphPanel = new JPanel(new BorderLayout());
graphPanel.add(graphComponent);
add(graphPanel);
}
public void initGraphSettings(){
Map<String, Object> style = graph.getStylesheet().getDefaultEdgeStyle();
style.put(mxConstants.STYLE_ALIGN, true);
style.put(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_TOPTOBOTTOM);
graph.setCellsCloneable(false);
graphComponent.setConnectable(false);
graphComponent.getViewport().setBackground(Color.WHITE);
new mxRubberband(graphComponent);
}
public mxGraph getGraph(){
return graph;
}
public void addToGraph(ArrayList<SaveDataElement> saveData){
for (int i = 0; i < saveData.size(); i++) {
String name = saveData.get(i).getName();
int vertPosX = saveData.get(i).getPosX();
int vertPosY = saveData.get(i).getPosY();
new AddGraphNode("node", name, "rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;", vertPosX, vertPosY);
}
Object[] cells = graph.getChildVertices(graph.getDefaultParent());
Object startCell = null;
Object endCell = null;
for (int i = 0; i < saveData.size(); i++){
for (int j = 0; j < cells.length; j++){
if (((mxCell)cells[j]).getAttribute("name").equals(saveData.get(i).getName()))
startCell = cells[j];
for (int k = 0; k < saveData.get(i).getTargets().size(); k++){
if (((mxCell)cells[j]).getAttribute("name").equals(saveData.get(i).getTargets().get(k))){
endCell = cells[j];
new AddGraphLink(startCell, endCell,"Link", "endArrow=classic;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;verticalAlign=top;verticalLabelPosition=bottom'");
}
}
}
}
}}
public class MenuBar extends JMenuBar {
MenuBar(Editor editor){
JMenuBar menuBar = new JMenuBar();
JMenuItem menuItem;
JMenu menu = new JMenu("File");
menuBar.add(menu);
menuItem = new JMenuItem("Add");
menuItem.addActionListener(new ActionListener() {
#java.lang.Override
public void actionPerformed(ActionEvent e) {
//Setting up some data to create nodes and links
ArrayList<SaveDataElement> saveData = new ArrayList<SaveDataElement>();
ArrayList<String> targetsForTestX = new ArrayList<String>();
targetsForTestX.add("Test Y");
targetsForTestX.add("Test Z");
saveData.add(new SaveDataElement("Test X", 200, 300, targetsForTestX));
ArrayList<String> targetsForTestY = new ArrayList<String>();
saveData.add(new SaveDataElement("Test Y", 300, 420, targetsForTestY));
ArrayList<String> targetsForTestZ = new ArrayList<String>();
saveData.add(new SaveDataElement("Test Z", 100, 420, targetsForTestZ));
editor.addToGraph(saveData);
}
});
menu.add(menuItem);
menuItem = new JMenuItem("Load 1");
menuItem.addActionListener(new ActionListener() {
#java.lang.Override
public void actionPerformed(ActionEvent e) {
//Setting up some data to create nodes and links
ArrayList<SaveDataElement> saveData = new ArrayList<SaveDataElement>();
ArrayList<String> targetsForTest1 = new ArrayList<String>();
targetsForTest1.add("Test 2");
saveData.add(new SaveDataElement("Test 1", 40, 40, targetsForTest1));
ArrayList<String> targetsForTest2 = new ArrayList<String>();
saveData.add(new SaveDataElement("Test 2", 200, 40, targetsForTest2));
Editor editorNew = new Editor(saveData);
new MenuBar(editorNew);
editorNew.setVisible(true);
editor.dispose();
}
});
menu.add(menuItem);
editor.setJMenuBar(menuBar);
}}
public class SaveDataElement {
String name;
int posX, posY;
ArrayList<String> targets;
public SaveDataElement(String name, int posX, int posY, ArrayList<String> targets){
this.name = name;
this.posX = posX;
this.posY = posY;
this.targets = targets;
}
public String getName() {
return name;
}
public int getPosX() {
return posX;
}
public int getPosY() {
return posY;
}
public ArrayList<String> getTargets() {
return targets;
}}
public class AddGraphNode extends Editor {
public AddGraphNode(String tag, String name, String style, int vertPosX, int vertPoxY){
this.getGraph().getModel().beginUpdate();
Object parent = this.getGraph().getDefaultParent();
Document doc = mxDomUtils.createDocument();
Element entity = doc.createElement(tag);
entity.setAttribute("name", name);
try
{
Object v1 = this.getGraph().insertVertex(parent, "1",entity, vertPosX, vertPoxY, (int)(name.length()*8) ,
40, style);
}
finally
{
this.getGraph().getModel().endUpdate();
}
}}
public class AddGraphLink extends Editor{
public AddGraphLink(Object v1, Object v2, String relation, String style){
this.getGraph().getModel().beginUpdate();
Object parent = this.getGraph().getDefaultParent();
try
{
this.getGraph().insertEdge(parent, null, relation, v1, v2,style);
}
finally
{
this.getGraph().getModel().endUpdate();
}
}}
When using the the add menu item some nodes and links are added to the graph and with the load 1 menu item a new Editor will be created (creating a new graph and graphComponent). However, the added nodes and links are still present on the new component.
Regarding the visually broken links I mentioned above, this does not occur...I will investigate this further. Despite that this might also be connected with the graphComponent problem.
I see 3 major problems in your code:
Inappropriate use of a static field: protected static mxGraph graph = new mxGraph() {
Inappropriate inheritance: public class AddGraphLink extends Editor {
And again, inappropriate inheritance: class AddGraphNode extends Editor {
By making the graph field static, changes made to one variable will be felt in all variables, and this is the likely cause for your so-called "artifacts". And the reason that you feel that you must make the field static is because since the two classes above are inheriting from Editor (again inappropriately). The solution is obvious:
Make the graph field an instance field, not a static one, and
Don't use inheritance where it doesn't belong. Instead your AddGraphXxxx classes should not extend Editor but rather should have Editor fields within them, one that you can set via the constructor, and one whose methods you can call, something like this, for example:
// protected static mxGraph graph = new mxGraph() { //!! **** NO ****
private mxGraph graph = new mxGraph() { //!! **** YES ****
.....
.....
public class AddGraphNode {
public AddGraphNode(Editor editor, String tag, String name, String style, int vertPosX, int vertPoxY) {
// **** note use of the editor parameter below ****
editor.getGraph().getModel().beginUpdate();
Object parent = editor.getGraph().getDefaultParent();
Document doc = mxDomUtils.createDocument();
Element entity = doc.createElement(tag);
entity.setAttribute("name", name);
try {
// **** same here ****
Object v1 = editor.getGraph().insertVertex(parent, "1", entity, vertPosX, vertPoxY,
(int) (name.length() * 8), 40, style);
} finally {
// **** and the same here ****
editor.getGraph().getModel().endUpdate();
}
}
}
and you would create this instance within Editor by passing in the this parameter:
new AddGraphNode2(this, "node", name,
"rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;",
vertPosX, vertPosY);
You would make simiar changes to the AddGraphLink class.
Side note, please check out the The Use of Multiple JFrames, Good/Bad Practice? to see why swapping JFrames is not the best program design, and how you can change the code to improve its structure and user experience.

Android MP Chart highlightValue not working, throws ArrayIndexOutOfBoundsException

I'm playing around with Android MP Chart lib to draw awesome charts.
I'm trying to highlight values on my chart, but it does not puts the highlight to the right place, or throws ArrayIndexOutOfBoundsException.
I've made a little dummy project for it. When user clicks on the next button, the highlight should move to positive direction.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
final int DATA_MAX_COUNT = 30;
List<MyData> list = new ArrayList<>(); ///<Dummy data stored in here
List<Entry> entries = new ArrayList<>(); ///<Entries for MP Chart
int highlightIndex = 0; ///<Chart's data index to be highlighted
CombinedChart combinedChart; ///<I use combined chart because there will be more data sets added later on
Button prevBtn; ///<Button for highlight control
Button nextBtn; ///<Button for highlight control
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
combinedChart = (CombinedChart) findViewById(R.id.chart);
prevBtn = (Button) findViewById(R.id.prev_btn);
prevBtn.setOnClickListener(this);
nextBtn = (Button) findViewById(R.id.next_btn);
nextBtn.setOnClickListener(this);
generateData();
drawChart();
}
#Override
public void onClick(View v) {
//Clicking buttons should move the highlighted value
if (v.equals(prevBtn)) {
if (highlightIndex > 0) {
highlightIndex--;
}
} else if (v.equals(nextBtn)) {
if (highlightIndex + 1 < DATA_MAX_COUNT) {
highlightIndex++;
}
}
//Does not work, throws exception
//combinedChart.highlightValue(new Highlight(highlightIndex, 0, 0));
//Does not work, throws exception
//combinedChart.highlightValue(highlightIndex, 0, false);
//Exception
// java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
// at com.github.mikephil.charting.data.CombinedData.getDataByIndex(CombinedData.java:152)
// at com.github.mikephil.charting.data.CombinedData.getEntryForHighlight(CombinedData.java:183)
// at com.github.mikephil.charting.charts.Chart.highlightValue(Chart.java:635)
// at com.github.mikephil.charting.charts.Chart.highlightValue(Chart.java:613)
//Works, but highlights value on chart with like x=0 and y= 190, wtf?
combinedChart.highlightValue(combinedChart.getHighlighter().getHighlight(highlightIndex, 0));
}
//Generating random data to a list
public void generateData() {
for (int i = 0; i < DATA_MAX_COUNT; i++) {
MyData myData = new MyData(new Random().nextInt(100) + 100);
list.add(myData);
}
}
//Simple func for adding data to entries and drawing chart
private void drawChart() {
CombinedData combinedData = new CombinedData();
for (int i = 0; i < list.size(); i++) {
MyData myData = list.get(i);
entries.add(new Entry(i, myData.getValue(), myData));
}
LineDataSet lineDataSet = new LineDataSet(entries, "My data list");
lineDataSet.setHighLightColor(Color.RED);
lineDataSet.setHighlightLineWidth(3);
LineData lineData = new LineData();
lineData.addDataSet(lineDataSet);
combinedData.setData(lineData);
combinedChart.setData(combinedData);
combinedChart.invalidate();
}
//Dummy data class
public static class MyData {
private int value;
public MyData(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
}
I don't get it why I'm getting
java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
Because what the hell is -1? and what is 10? There are not a single thing in my code which is 10, and why does any of the chart's functions getting -1?
I'm using
com.github.PhilJay:MPAndroidChart:v3.0.3
Please help if you can.
E D I T:
I've added combinedChart.setOnChartValueSelectedListener(this); to the chart.
With this callback onValueSelected(Entry, Highlight) I can test this thing in another way. It gives a Highlight object. If I does nothing in this callback, the chart draws the highlights well. If I call it programatically with the same X value, it throws the usual exception or draws the highlight to wrong position. (to zero)
See the callback:
#Override
public void onValueSelected(Entry e, Highlight h) {
float x = h.getX();
Log.i("Highlighted", "Actual highlight: " + x);
//Getting the same exception as above
//combinedChart.highlightValue(x, 0, false);
//Does not works, draws to x=0 position with any given x
combinedChart.highlightValue(combinedChart.getHighlighter().getHighlight(x, 0));
}
Here is solution:
Highlight high = new Highlight(highlightIndex, 0, 0);
high.setDataIndex(0);
combinedChart.highlightValue(high, false);
You need to add high.setDataIndex(0); line.
Explaination:
In Highlight constructor first parameter is X value, the value you increase or decrease. Second is index of graph you want to select. Since you have only one, you specify 0 there. Also you should specify it second time high.setDataIndex(0); (otherwise it is treated as -1, bug ! ) and your code will work:

Drop File on SWT Label with Image (DND)

Problem description:
The user should be able to drag an Image-File from his computer to a RCP Application. The drop-target is a SWT-Label which is generated through the Eclipse FormToolkit. (Eclipse Forms)
With the following code, the user is able to drag Image-Files as well as Images from a Browser and drop them on the label (works well).
The problem occurs, when the label shows a image:
lblImage.setImage()
In my example, I set the image of the label, after the user dropped a file. As a consequence, subsequent drags are no longer registered.
(dragEnter method is no longer invoked)
/** create label **/
Label lblImage = fFormToolkit.createLabel(fForm.getBody(), "");
GridData gd = new GridData();
gd.widthHint = 200;
gd.heightHint = 200;
lblImage.setLayoutData(gd);
/** drag drop support **/
int ops = DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT;
final FileTransfer fTransfer = FileTransfer.getInstance();
final ImageTransfer iTransfer = ImageTransfer.getInstance();
Transfer[] transfers = new Transfer[] { fTransfer, iTransfer };
DropTarget target = new DropTarget(fLblArtWork, ops);
target.setTransfer(transfers);
target.addDropListener(new DropTargetAdapter() {
#Override
public void drop(DropTargetEvent event) {
if (event.data instanceof String[]) {
String[] filenames = (String[]) event.data;
if (filenames.length > 0){
Image i = new Image(Display.getCurrent(), filepath);
lblImage.setImage(i);
}
} else if (event.data instanceof ImageData) {
Image i = new Image(Display.getCurrent(), data);
lblImage.setImage(i);
}
}
public void dragEnter(DropTargetEvent event) {
System.out.println("drag enter");
event.detail = DND.DROP_COPY;
}
});
Question: How do I register dragEnter Events on a SWT Label that shows an Image?
Thanks
In your example there were some problems that caused this not to compile for me. After I fixed the issues I was able to drag png files onto the component and each successive drop changed the image correctly.
Here are the changes:
Original
DropTarget target = new DropTarget(fLblArtWork, ops);
became:
DropTarget target = new DropTarget(lblImage, ops);
Original
Image i = new Image(Display.getCurrent(), filepath);
became:
Image i = new Image(Display.getCurrent(), filenames[0]);
Original
Image i = new Image(Display.getCurrent(), data);
became
Image i = new Image(Display.getCurrent(), (ImageData) event.data);
I also create my label the following way:
final Label lblImage = new Label(shell, SWT.NONE);
but that shouldn't make a difference.
I used SashForm here to set an background image from the local system. AS per your requirement I have done the text and label also but I didn't set. You can set it by the labelobject.setImage(image);
final SashForm sashForm = new SashForm(composite, SWT.BORDER);
sashForm.setBounds(136, 10, 413, 237);
final Label lblHello = new Label(composite, SWT.NONE);
DragSource dragSource = new DragSource(lblHello, DND.DROP_NONE);
ImageTransfer imgTrans=ImageTransfer.getInstance();
FileTransfer fileTrans=FileTransfer.getInstance();
Transfer[] transfer=new Transfer[] { fileTrans,imgTrans,TextTransfer.getInstance() };
DropTarget dropTarget = new DropTarget(sashForm, DND.DROP_NONE);
dropTarget.setTransfer(transfer);
dragSource.setTransfer(transfer);
lblHello.setBounds(27, 219, 55, 15);
lblHello.setText("Hello");
dragSource.addDragListener(new DragSourceAdapter() {
#Override
public void dragStart(DragSourceEvent event) {
event.doit=true;
}
});
//Drop Event
dropTarget.addDropListener(new DropTargetAdapter() {
#Override
public void drop(DropTargetEvent event) {
System.out.println(event.detail);
//String path = System.getProperty("C:\\Users\\Public\\Pictures\\Sample Pictures\\Desert.jpg");
Image image=new Image(display, "C:\\Users\\Public\\Pictures\\Sample Pictures\\Desert.jpg");
sashForm.setBackgroundImage(image);
}
});
Easy Way : Drop File on SWT Label with Image (DND)
The drop event occurs when the user releases the mouse over the Drop target.
final CLabel lblNewLabel = new CLabel(parent, SWT.BORDER);
lblNewLabel.setBounds(10, 43, 326, 241);
lblNewLabel.setText("Drop Target");
// Allow data to be copied or moved to the drop target
DropTarget dropTarget = new DropTarget(lblNewLabel, DND.DROP_MOVE| DND.DROP_COPY | DND.DROP_DEFAULT);
// Receive data in Text or File format
final TextTransfer textTransfer = TextTransfer.getInstance();
final FileTransfer fileTransfer = FileTransfer.getInstance();
Transfer[] types = new Transfer[] {fileTransfer, textTransfer};
dropTarget.setTransfer(types);
// DropTargetEvent
dropTarget.addDropListener(new DropTargetAdapter() {
#Override
public void drop(DropTargetEvent event) {
if (textTransfer.isSupportedType(event.currentDataType)) {
String text = (String)event.data;
lblNewLabel.setText(text);
}
if (fileTransfer.isSupportedType(event.currentDataType)){
//clear Label Text
lblNewLabel.setText("");
//list out selected file
String[] files = (String[])event.data;
for (int i = 0; i < files.length; i++) {
String[] split = files[i].split("\\.");
String ext = split[split.length - 1];
// Set Images format "jpg" and "png"
if(ext.equalsIgnoreCase("jpg") || ext.equalsIgnoreCase("png"))
{
lblNewLabel.setImage(SWTResourceManager.getImage(files[i]));
}
else
{
lblNewLabel.setText(files[i]);
}
}//end for loop
}
}//End drop()
});//End addDropListener

Categories

Resources