ImageJ, roiManager("add") - java

It's my first question in StackOverflow.
I have a doubt about roiManager("add") macro command. I'm trying to insert a macro content inside a plugin but im trying to understand what is adding to the roi manager. Here is the code:
run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Masks display clear record");
for (i=0; i<nResults; i++){
x = getResult('XStart', i);
y = getResult('YStart', i);
doWand(x,y);
roiManager("add");
}
I dont sure if the roiManager("add") is inserting the "doWand" result or another thing.
If someone helps me I will be very grateful. Thanks.
Edit:
Now I'm trying to develop the Macro with Java classes but I'm not sure how to add particles to the roi manager with the RoiManager class. I put the code here:
ij.plugin.frame.RoiManager roiManager = ij.plugin.frame.RoiManager.getInstance();
IJ.run("Convert to Mask");
IJ.run("Fill Holes");
IJ.run("Set Scale...", "distance=1 known="+pixelSize+" pixel=1 unit=um");
IJ.run("Analyze Particles...", "size=0-Infinity circularity=0.00-1.00 show=Masks display clear record");
// add the particles to the roiManager
ResultsTable rt = Analyzer.getResultsTable();
int nResults = rt.getCounter();
for (int i=0; i<nResults; i++) {
int x = Integer.parseInt(rt.getStringValue("XStart", i));
int y = Integer.parseInt(rt.getStringValue("YStart", i));
int doWandResult = IJ.doWand(x,y);
//roiManager.add(IJ.getImage(), Roi¿?, doWandResult); //¿?¿?¿?¿?¿
}

If you just want to add the results of Analyze Particles to the ROI Manager, use the option Add to Manager:
run("Analyze Particles...", "add");
Otherwise, you can add single ROIs as you propose, using:
the Macro language
roiManager(add) adds the current selection to the ROI Manager, as if you used Edit > Selection > Add to Manager.
In your macro, that means the selection created by doWand(x,y) is added to the ROI Manager.
See also the macro language documentation.
a Java plugin:
I recommend using the Recorder (Plugins > Macros > Record...) in Java mode to get the required code. In a plugin, you could use for example:
IJ.run(imp, "Analyze Particles...", "add");
or
import ij.plugin.frame.RoiManager;
...
RoiManager rm = RoiManager.getInstance();
rm.addRoi(imp.getRoi());
See also the RoiManager javadoc.

Related

How can I obtain relevant params, classes, and methods from a .groovy script from Java?

I have a Java plugin for a larger application that does image analysis using the ImageJ library. One client who switched to our software has been using Groovy scripts to define specific rules and parameters for when they perform the analysis in ImageJ. They would like our software to be able to accept the Groovy scripts as well, as they'll be working within our GUI as well as ImageJ.
They will provide a written script.groovy to the plugin, but I won't always know exactly what parameters, methods, and classes are present and what changes to the logic are in the .groovy file.
I've been looking into the GroovyClassLoader documentation, and after referencing Groovy in Action, 2nd Edition I have a better idea of how to create and send bindings and whatnot but I can't figure out where to start writing the logic for interpreting the contents of a static Groovy file. An ideal solution would be the user having one script that works in both programs, and my plugin determines what is relevant.
Is there any way to parse out individual parts of a Groovy file so that I might map them to our parameters and change the Java plugin's behavior accordingly?
Edit: Context
Our software performs real-time image analysis on stained tissue slides. Some of our users also use "Program X" within its GUI to perform analysis on images that have already been taken. The Java plugin accesses the logic from the other program, allowing our users to use features they're familiar with in real-time.
The Groovy script file.groovy that the user gives to Program X has some functions that feed data to the UI portions of the software that we don't need. I'd like to only parse our relevant portions of the script.
Edit: Sample File, and what I'd like to parse:
The .groovy file begins with some parameters, which are no use to me, as well as some methods for defining image background, also no use as my program does this automatically, where "Program X" does not:
/* imports */
//PARAMETER AREA//
//PARAMETERS FOR IMAGES WITH UM//
double requested_pixel_size = 0.5
double background_radius = 8
double median_filter_radius = 0
double sigma = 1.5
double minimum_area = 10
double maximum_area = 400
double threshold = 0.1
//PARAMETER AREA ENDS//
def openingReconstruction(final ImageProcessor ip, final ImageProcessor ipBackground, final double radius, final double maxBackground) {
final RankFilters rf = new RankFilters()
ipBackground.setRoi(ip.getRoi())
rf.rank(ipBackground, radius, RankFilters.MIN)
ByteProcessor bpMask = null
if (!Double.isNaN(maxBackground) && maxBackground > 0) {
int w = ip.getWidth()
int h = ip.getHeight()
for (int i = 0; i < w * h; i++) {
if (ipBackground.getf(i) > maxBackground) {
if (bpMask == null)
bpMask = new ByteProcessor(w, h)
bpMask.setf(i, 1f)
}
}
if (bpMask != null) {
rf.rank(bpMask, radius * 2, RankFilters.MAX)
for (int i = 0; i < w * h; i++) {
if (bpMask.getf(i) != 0f) {
ipBackground.setf(i, Float.NEGATIVE_INFINITY)
}
}
}
}
Then there are some area which actually enhance our program, and I need to be able to implement:
def detect(double key_value, PathObject parentObject, int Choose_detection_image, ParameterList params) {
def viewer = QPEx.getCurrentViewer()
ImageData<BufferedImage> imageData = viewer.getImageData()
println("Program starts.....")
The above code snippet will eventually call a modified version of the detection class which I need:
detect(key_value, parentObject, Choose_detection_image, params)
class WatershedCellDetection2 {
protected ObjectDetector<BufferedImage> createDetector(ImageData<BufferedImage> imageData, ParameterList params, double key_value) {
ObjectDetector<BufferedImage> detector = new NewCellDetector(key_value)
//insert the key_value in original detector.
return new DetectorWrapper<>(detector)
}
There are a few overloaded methods and other versions of the WatershedCellDetection that are used depending on what parameters are present, but as long as I know how to parse out one I can determine which one is best for each scenario.
There is a lot of code built into the functions that do things like update the help text in the GUI of "Program X" that are irrelevant to my program's UI since this is all interacting with a Java plugin of a C# program.

Eclipse syntax coloring plugin

I need to develop an Eclipse plugin that can "color" the same occurrence of a variable/value/tag in XML as the JAVA editor does.
I'm using the default XML Editor from eclipse, and am currently able to put a grey background on the selected words with the following code :
for (Point p : offsets){
TextPresentation t = new TextPresentation();
t.replaceStyleRange(new StyleRange( (int)p.getX(),
(int)(p.getY() - p.getX()),
null,
Color.win32_new(null, 0xDDDDDD)));
fText.changeTextPresentation(t, true);
}
My problem is that I can't recover the default style if the user tries to select another variable/tag/value. The text will not set its natural coloring after loosing the focus. For the moment, I am using hard-coded RGB values to set the defaults colors, BUT it is only "working" if the user kept the Eclipse default theme (white theme).
Is there a way to ask the document for a complete syntax coloring re-validation ?
Thanks for reading.
I found an answer by myself.
Here it is :
before changing the style of the selection, you should first save the current style. Use a similar structure:
private ArrayList<Point> offsets = new ArrayList<Point>();
private ArrayList<Color> foregroundgColor = new ArrayList<Color>();
Then you put all the styles/offsets of the occurences in this structure, in a loop statement :
offsets.add(new Point(i,j));
fgColor.add(fText.getTextWidget().getStyleRangeAtOffset(i).foreground);
You can now apply the "highlighting" (grey background on the occurences) :
for (Point p : offsets){
TextPresentation t = new TextPresentation();
t.replaceStyleRange(new StyleRange( (int)p.getX(),
(int)(p.getY() - p.getX()),
null,
Color.win32_new(null, 0xDDDDDD)));
fText.changeTextPresentation(t, true);
}
Finally, when the selected occurences loses the focus, you restore the default styles :
for (int i = 0; i < offsets.size(); i++){
Point p = offsets.get(i);
TextPresentation t = new TextPresentation();
t.replaceStyleRange(new StyleRange( (int)p.getX(),
(int)(p.getY() - p.getX()),
fgColor.get(i),
null));
fText.changeTextPresentation(t, true);
}
offsets.clear();
fgColor.clear();

Creating dynamic amount of components in FXML

I made a note card program that can help you study with JavaFX. It saves the class through XML and on boot up, it finds the XML files and adds them to an ArrayList called allProjects of type NoteCardSet, an ArrayList of NoteCards. With this, I made a dynamic amount of buttons that puts them 4 columns wide. Here is the code for that:
int amountPerRow = 4;
int current = 0;
int row = 0;
for (NoteCardSet noteCardSet : allProjects) {
Button b = new Button(noteCardSet.getName());
GridPane.setConstraints(b, current, row);
centerMenu.getChildren().add(b);
b.setOnAction(e -> {
border.setCenter(noteCardSetLayout(noteCardSet));
});
if (current < amountPerRow - 1)
{
current++;
}
else if (current >= amountPerRow - 1)
{
current = 0;
row++;
}
}
Obviously this is creatable in JavaFX but is it possible to created this in FXML?
No you cannot do this in FXML. There is no way to write a LOOP in fxml. If you are just considered about a Button, then you may use SceneBuilder and drag-drop multiple buttons.
Though, if you are considered about a more complex UI and want to repeat them, you can create a separate FXML and include it as many time as you need using <fx:include>.
You can also load the same fxml multiple times using a loop and put all the concerned data inside the initialize(), but this might not be the best solution you are looking for.

GWT infinite scroll with discarding start-of-list results

Looking for a GWT DataGrid component which implements infinite scroll, BUT also makes sure to discard the results no longer visible on the screen : such as the previously loaded results that are not shown anymore.
This is to avoid a memory hog.
I've been trying to find this on Google, but no luck so far.
Please note : I could take a JS library and adapt it to what I need, but I don't think it would work good with GWT's DataGrid component.
Edit: I am interested specifically in an infinite scroll which ALSO discards/releases the topmost results that are not visible (and loads them up as appropriate).
Any ideas ?
As a matter of fact the showcase example has an infinite scrolling CellList. (you can find the code there).
Although this was done with a CellList the same principles should also apply to a DataGrid.
Check out the ShowMorePagerPanel.java file.
Update:
The onScroll function of ShowMorePagerPanel.java will add the new records at the bottom. However you can easily change the behavior:
Something along the lines (not tested tough):
HasRows display = getDisplay();
if (display == null) {
return;
}
boolean loadData = false;
// If scrolling up, change newStart
int oldScrollPos = lastScrollPos;
lastScrollPos = scrollable.getVerticalScrollPosition();
// get the current visible Range
Range currentRange = display.getVisibleRange();
if (oldScrollPos >= lastScrollPos) {
int newStart = Math.max(
currentRange.getStart() - incrementSize,0);
loadData = true;
}
int maxScrollTop = scrollable.getWidget().getOffsetHeight()
- scrollable.getOffsetHeight();
if (lastScrollPos >= maxScrollTop) {
// We are near the end, so increase the page size.
int newPageSize = Math.min(
display.getVisibleRange().getLength() + incrementSize,
display.getRowCount());
loadData = true;
}
if (loadData) {
display.setVisibleRange(newStart, newPageSize);
}

Java Default Highlighter

Im using the DefaultHightlighter.DefaultHightlighterPainter to highlight text within a java text pane.
I want to remove all highlights (there could be more than one string highlighted) and want it to return the locations of the strings where the highlight has been removed, so obviously I cant use
pseudoCodeTextPane.getHighlighter().removeHighlight(highlight);
Can anyone help?
Thanks
How about something like
Highlighter.Highlight[] highlights = pseudoCodeTextPane.getHighlighter().getHighlights();
int[] startOffsets = new int[highlights.length];
int[] endOffsets = new int[highlights.length];
for (int i = 0; i < highlights.length; ++i) {
startOffsets[i] = highlights[i].getStartOffset();
endOffsets[i] = highlights[i].getEndOffset();
}
pseudoCodeTextPane.getHighlighter().removeAllHighlights();
// now do whatever processing you want to do with the highlight locations
If you remove all highlights (I suppose with removeAllHighlights) you can getHighlights before that and use the information you receive there.

Categories

Resources