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();
Related
I've started building a small search engine for an index I created using Lucene. I use the GWT to create the GUI I like but I'm stuck in a problem. I am trying to add some results inside a FlowPanel which is inside the center of a DockLayoutPanel so I can have scrolling the page as I like. My problem is (as I found out ) that in order for scrolling to work ( and not have the browser window cut my results ) is to make every DockLayoutPanel child to not have position:absolute. My problem is that I cannot remove it ( or I don't know how ). When I disable it from chrome inspector scrolling works but when I re-enable it it cuts the flowPanel. Here is the java code :
public static void loadCellTrees(HashMap<Integer,LinkedHashMap<String,String>> searchResults, List<RootCategories> list)
{
VerticalPanel westTrees = new VerticalPanel();
TreeViewModel treeModel = new CellTreeWidget(list);
CellTree tree = new CellTree(treeModel, null);
HTMLBuilder builder = new HTMLBuilder(searchResults);
tree.setStyleName("tree");
tree.setAnimationEnabled(true);
dock.clear();
westTrees.clear();
westTrees.getElement().setAttribute("align", "center");
westTrees.add(tree);
FlowPanel resultsPanel = new FlowPanel();
resultsPanel.setStyleName("resultsPanel");
for(int i=0; i<searchResults.size(); i++)
{
HTML box = builder.toHTML(i);
box.setStyleName("resultBox");
resultsPanel.add(box);
}
dock.addWest(westTrees, 20);
dock.addNorth(RootPanel.get("wrap"),20);
dock.add(resultsPanel);
}
at the beginning of my code I add the dock (DockLayoutPanel ) to my RootLayoutPanel.
as I show at the first image... with position set to absolute I can have the scrollbar and the results are cut, but if I disable position: absolute as shown in the second pic
the scrollbar is enabled and I can have full access to all of my results.
The scrollbar is set like this :
RootLayoutPanel.get().getWidgetContainerElement(dock).getStyle().setOverflowY(Overflow.AUTO);
What I am trying to do is remove position for every dockLayoutPanel's child or set it to something else that doesn't creates me a problem.
I found a solution. On CSS styling simply I had to write
.cw-DockPanel > div {
position : initial !important;
}
If anyone has to suggest a better way than to use !important i would be glad to hear it.
After I solved my problem on docx4j previously, I'm be able to use it now.
I just try to run the sample code from this link
http://www.smartjava.org/content/create-complex-word-docx-documents-programatically-docx4j
with some modification.
let's say I have two documents.
One is main template that have about 2-3 pages.
Second one have only 1 paragraph of text with various of style (Bold, Italic, Underline, Font Size, etc).
I want to replace a parameter in my template with a paragraph in the second document.
The result is it can replace my parameter with a paragraph but there is a problem with style. What I can observe with many experiment is:
Indent still there
New Line still there
Underline move along too
Font Color/ Font Size is working
Bold/Italic not come along
Font Family not come along
Here is my code
private static void replaceParagraph2(String placeholder, WordprocessingMLPackage template, ContentAccessor addTo) throws Exception {
//get the paragraph
WordprocessingMLPackage paragraph_template = getTemplate("./resources/input/paragraph.docx");
List<Object> paragraphs_LineList = getAllElementFromObject(paragraph_template.getMainDocumentPart(), P.class);
// get the template
List<Object> template_lineList = getAllElementFromObject(template.getMainDocumentPart(), P.class);
int position = 0;
P toReplace = null;
//find placeholder position
for (Object p : template_lineList) {
List<Object> texts = getAllElementFromObject(p, Text.class);
for (Object t : texts) {
Text content = (Text) t;
if (content.getValue().equals(placeholder)) {
toReplace = (P) p;
position = template_lineList.indexOf(toReplace);
break;
}
}
}
//add paragraph into template
for (int i = 0; i < paragraphs_LineList.size(); i++) {
P para = (P) XmlUtils.deepCopy(paragraphs_LineList.get(i));
addTo.getContent().add(position + 1 + i, para);
}
// remove the placeholder on the template
((ContentAccessor)toReplace.getParent()).getContent().remove(toReplace);
}
Do I missing something?
PS. I debug to check the object of template. It seems that bold value in the P object is config to null. (It's booleanTrueifNull type I think.)
The formatting comes from direct formatting (in rPr and pPr elements in the paragraph), and also from the styles part. If no style is specified, the default styles will be used.
You'll need to look at the XML in your paragraph, and in the styles part.
Microsoft Word (2010 at least) has a useful "Reveal Formatting" sidebar which can help you to understand where the formatting is coming from. Click the "distinguish style source" at the bottom.
There is code in docx4j (used by its PDF output) to determine the effective formatting. I guess you could use that to specifically apply the effective formatting from your source to each run in your target.
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.
Context
I've been working on dynamic PDF generation for a while now, and I've come across my final requirement. Alas, it's a nightmare. I'm using the iText library, version 2.1.7.
I'm basically trying to get a formatting like the top row (which I just mocked up in paint). The other rows are how it looks at the moment, but I'm having some real trouble with getting them to line up properly!
Code
The code being used to generate each color coded block is here:
String currentPrice = p.getPrice();
String timeStr = p.getTime();
Chunk price = new Chunk(currentPrice);
Chunk time = (Chunk) generatePdfElement("Timestamp", timeStr);
if (priceDbl > lastPrice) {
// set color to blue.
price.setBackground(WebColors.getRGBColor("#7777FF"));
time.setBackground(WebColors.getRGBColor("#7777FF"));
} else if (priceDbl < lastPrice) {
// set to red.
price.setBackground(WebColors.getRGBColor("#FF0000"));
time.setBackground(WebColors.getRGBColor("#FF0000"));
}
Paragraph pricePara = new Paragraph();
pricePara.add(price);
pricePara.add(generateBreakLine());
pricePara.add(time);
pricePara.add(generateBreakLine());
// Add the new price data to the list of all the prices for this cell.
allPrices.add(pricePara);
allPrices is then added to a paragraph and put into the cell:
Paragraph pricesCellValue = new Paragraph();
pricesCellValue.addAll(allPrices);
PdfPCell pricesCell = new PdfPCell(pricesCellValue);
pricesCell.setBackgroundColor(WebColors.getRGBColor(getRowStr()));
selectionsTable.addCell(pricesCell);
// Add each cell to the table to create the row.
The approaches I've tried
I tried the obvious, which was removing the last breakline from each Chunk. This didn't work, and it just looked exactly the same, although each Chunk was closer together.
I also tried changing from Paragraph to Phrase, which means the code looked like this:
Phrase pricePara = new Phrase();
pricePara.add(price);
pricePara.add(generateBreakLine());
pricePara.add(time);
//pricePara.add(generateBreakLine());
// Add the new price data to the list of all the prices for this cell.
allPrices.add(pricePara);
And this was the result:
So now I'm fresh out of ideas! Does anyone else have any suggestions, or some experience with iText in this area?
Edit
Just for clarity, generateBreakLine() generates a new empty Paragraph object.
I used a nested PdfPTable in the last cell, to format the positioning of each Phrase. Works like a dream!
I got a relatively easy question - but I cannot find anything anywhere to answer it.
I use a simple SWT table widget in my application that displays only text in the cells. I got an incremental search feature and want to highlight text snippets in all cells if they match.
So when typing "a", all "a"s should be highlighted.
To get this, I add an SWT.EraseItem listener to interfere with the background drawing. If the current cell's text contains the search string, I find the positions and calculate relative x-coordinates within the text using event.gc.stringExtent - easy.
With that I just draw rectangles "behind" the occurrences.
Now, there's a flaw in this. The table does not draw the text without a margin, so my x coordinate does not really match - it is slightly off by a few pixels! But how many?? Where do I retrieve the cell's text margins that table's own drawing will use? No clue. Cannot find anything.
Bonus question: the table's draw method also shortens text and adds "..." if it does not fit into the cell. Hmm. My occurrence finder takes the TableItem's text and thus also tries to mark occurrences that are actually not visible because they are consumed by the "...".
How do I get the shortened text and not the "real" text within the EraseItem draw handler?
#Override
public void handleEvent( final Event event ) {
final TableItem ti = (TableItem) event.item;
final int index = event.index;
final GC gc = event.gc;
if( ti == null || currentSwyt.isEmpty() ) {
return;
}
final String text = ti.getText( index );
if( !text.contains( currentSwyt ) ) {
return;
}
// search text is contained
final String[] parts = text.split( currentSwyt );
final int swytWidth = gc.stringExtent( currentSwyt ).x;
// calculate positions, must be relative to the text's start
int x = event.x; // THIS IS THE PROBLEM: event.x is not enough!
final int[] pos = new int[parts.length - 1];
for( int i = 0; i < parts.length - 1; i++ ) {
x += gc.stringExtent( parts[i] ).x;
pos[i] = x;
}
final Color red = event.display.getSystemColor( SWT.COLOR_RED );
final Color oldBackground = gc.getBackground();
gc.setBackground( red );
for( int j = 0; j < pos.length; j++ ) {
gc.fillRectangle( pos[j], event.y, swytWidth, event.height );
}
gc.setBackground( oldBackground );
event.detail &= ~SWT.BACKGROUND;
}
I think it would be quite useful for you to have a look at TableViewer and StyledCellLabelProvider. That will make your task a lot easier I think considering the kind of text formatting you require. Since the drawing is than completely handled by the label provider, you can avoid these pesky margin issues.
As for almost all SWT Widgets, this might be OS dependent. The actual "drawing" of the table is done using OS resources.
However, it might be worth having a look at TableItem#getTextBounds(int).
It returns a Rectangle that should reflect the margins.
For your bonus question: I have never seen the text being shortened automatically in my applications. In fact I had a hard time doing this myself. But that might as well be OS dependent, since I use Linux.