generating swt shell at the center of its parent shell - java

I have SWT wizard page as my parent shell , for creating another shell on click of button i am writing following code
Shell permissionSetShell = new Shell(Display.getCurrent().getActiveShell(), SWT.CENTER|SWT.DIALOG_TRIM|SWT.APPLICATION_MODAL);
permissionSetShell.setText(PropertyClass.getPropertyLabel(QTLConstants.PERMISSION_SET_COLUMN_LABEL));
// Add shell to the center of parent wizard
permissionSetShell.setLayout(componentsRenderer.createGridLayout(1, false, 0, 5, 0, 0));
Monitor primary = Display.getCurrent().getPrimaryMonitor ();
Rectangle bounds = primary.getBounds ();
Rectangle rect = Display.getCurrent().getActiveShell().getBounds ();
int x = bounds.x + (bounds.width - rect.width) / 2;
int y = bounds.y + (bounds.height - rect.height)/2;
permissionSetShell.setLocation (x, y);
but as the child shell means this shell is not placed at the center of SWT wizard that is parent shell why?

Rectangle screenSize = display.getPrimaryMonitor().getBounds();
shell.setLocation((screenSize.width - shell.getBounds().width) / 2, (screenSize.height - shell.getBounds().height) / 2);

If you are writing a dialog or a child component you may want to use getParent instead of asking the display for the primary monitor so that the window is centered on the current screen for multiple monitor setups.
Rectangle parentSize = getParent().getBounds();
Rectangle shellSize = shell.getBounds();
int locationX = (parentSize.width - shellSize.width)/2+parentSize.x;
int locationY = (parentSize.height - shellSize.height)/2+parentSize.y;
shell.setLocation(new Point(locationX, locationY));

I think the best would be to use style SWT.SHEET for such dialog.

I just ran into this same problem. The solution I got is a little different. This might help others with the same issue. The context is a shell (hoverShell) that hovers over the parent (shell) for a couple of seconds displaying a message.
private void displayMessage(Shell shell, String message) {
Shell hoverShell = new Shell(shell, SWT.ON_TOP);
hoverShell.setLayout(new FillLayout());
Label messageLabel = new Label(hoverShell, SWT.NONE);
messageLabel.setText(message);
Point shellLocation = shell.getLocation();
hoverShell.pack();
hoverShell.setLocation(shellLocation.x + (shell.getSize().x / 2) - (hoverShell.getSize().x / 2), shellLocation.y + 40);
hoverShell.open();
Display.getDefault().timerExec(2000, new Runnable() {
#Override
public void run() {
hoverShell.dispose();
}
});
}
In a nutshell this is the following formula:
child_location.x = parent_location.x + .5*(parent_width.x) - .5*(child_width.x)
If you want y then it's the exact same I believe. May depend if the top border of the window is calculated.

tried, tested and working code:
int width = display.getClientArea().width;
int height = display.getClientArea().height;
shell.setLocation(((width - shell.getSize().x) / 2) + display.getClientArea().x, ((height - shell.getSize().y) / 2) + display.getClientArea().y);

Related

How to make Accessible link annotation with PDFBOX

I'm trying to create a PDF that's PAC3 approved for accessibility but I'm having an issue when it comes to the links I'm writing. This is the code I have one function that draws the text and tags it given the structType (this function is from https://github.com/chris271/UAPDFBox/blob/a8b280bcbc838722ba872d6b382b8fd45bd35303/src/com/wi/test/util/PDFormBuilder.java)
public PDStructureElement drawElement(Cell textCell, float x, float y, float height,PDStructureElement parent,
String structType, int pageIndex) throws IOException {
//Set up the next marked content element with an MCID and create the containing H1 structure element.
PDPageContentStream contents = new PDPageContentStream(pdf, pages.get(pageIndex),
PDPageContentStream.AppendMode.APPEND, false);
currentElem = addContentToParent(null, structType, parent);
setNextMarkedContentDictionary();
contents.beginMarkedContent(COSName.ARTIFACT, PDPropertyList.create(currentMarkedContentDictionary));
//Draws the cell itself with the given colors and location.
drawDataCell(textCell, x, y + height, height * 2, contents);
contents.endMarkedContent();
addContentToParent(COSName.ARTIFACT, null, currentElem);
contents.close();
//Set up the next marked content element with an MCID and create the containing P structure element.
contents = new PDPageContentStream(pdf, pages.get(pageIndex), PDPageContentStream.AppendMode.APPEND, false);
setNextMarkedContentDictionary();
contents.beginMarkedContent(COSName.P, PDPropertyList.create(currentMarkedContentDictionary));
//Draws the given text centered within the current table cell.
drawCellText(textCell, x, y + height + textCell.getFontSize(), contents, pages.get(pageIndex).getResources());
//End the marked content and append it's P structure element to the containing P structure element.
contents.endMarkedContent();
addContentToParent(COSName.P, null, currentElem);
contents.close();
return currentElem;
}
After it's written to the page I call a separate function to add the underline for hyperlinks
public void drawLink(float firstX,float firstY,float lastX,float width, float height,int pageNum, float lastCharWidth) throws IOException {
PDAnnotationTextMarkup markup = new PDAnnotationTextMarkup(PDAnnotationTextMarkup.SUB_TYPE_UNDERLINE);
PDRectangle position = new PDRectangle();
position.setLowerLeftX(firstX);
position.setLowerLeftY(firstY);
position.setUpperRightX(firstX + width);
position.setUpperRightY(firstY + height);
markup.setRectangle(position);
//need to modify quadpoints lastX so it's inline with link
float quadPoints[] = {firstX, firstY + height + 2,
lastX + lastCharWidth, firstY + height + 2,
firstX, firstY - 5,
lastX + lastCharWidth, firstY - 5};
markup.setQuadPoints(quadPoints);
PDColor color = new PDColor(new float[]{ 1, 15/ 255F, 1 }, PDDeviceRGB.INSTANCE);
markup.setColor(color);
pdf.getPage(pageNum).getAnnotations().add(markup);
}
The result of calling these 2 functions are below, it draws the link properly but I'm missing information for the annotation. My question is how do I utilize the PDAnnotation object to create a PAC3 approved annotation?
Image of PAC3 detailed results

SWT drop cursor position on canvas

I'm making a simple "paint" application in JAVA. I would have wanted that when the person clicks the canvas, and make a drag and drop, a listener get the drop cursor location, but I don't find how make a drop listener. How can I find the location of the cursor when the user stop his click?
I have the following code for the drag :
Canvas paintC = new Canvas(shell, SWT.NONE);
paintC.addDragDetectListener(new DragDetectListener() {
public void dragDetected(DragDetectEvent arg0) {
Point controlRelativePos = new Point(arg0.x, arg0.y);
displayRelativePos1 = paintC.toDisplay(controlRelativePos);
GC gc = new GC(paintC);
gc.setBackground(SWTResourceManager.getColor(SWT.COLOR_YELLOW));
gc.fillRectangle(arg0.x, arg0.y, 90, 60);
}
});
Should I a drag function in order to get the latest position?
Edit: I've tried this, but it didn't work :
dropTarget.addDropListener(new DropTargetAdapter() {
#Override
public void drop(DropTargetEvent event) {
displayRelativePos2 = dropTarget.getDisplay().getCursorLocation();
hauteur = displayRelativePos2.y - displayRelativePos1.y;
largeur = displayRelativePos2.x - displayRelativePos1.x;
GC gc = new GC(paintC);
gc.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));
gc.fillRectangle(displayRelativePos1.x, displayRelativePos1.y, largeur, hauteur);
nbFormesAff = nbFormes +1;
forme = "Rectangle" + nbFormesAff;
pos = displayRelativePos1.x + ", " + displayRelativePos1.y +"\nhauteur:" + hauteur +" largeur:"+ largeur;
}
DropTargetEvent has x and y fields which contain the Display relative location of the cursor.
Point displayRelativeDrop = new Point(event.x, event.y);
Your fillRectangle must use points which are relative to the Control (paintC) not the display. Use Control.toControl(point) to convert from display relative to control relative.
You should also not try to draw the control in the drop method. Just call redraw on the control and do the drawing in a paint listener.

Libgdx: Is there an easy way to center text on each axis on a button?

I have been trying to figure out a way to center text on a button, but can't find an easy, multi-purpose way to. I can do it, but it will only work for a certain string, not for any string. i would like to know if there is a way to center any string on a button. My button in this case is 185x50.
I have been able to center this button on the screen, like so:
buttonX = WIDTH / 2 - (screen.getRegionWidth() / 2);
buttonY = HEIGHT / 2 - (screen.getRegionHeight() / 2);
Any help would be much appreciated. :)
Updated the answer to libgdx version 1.7.1-SNAPSHOT:
The easiest way to do this, is to use the TextButton class from libgdx. The text from a TextButton is centered by default. This still works!
Updated example:
final BitmapFont font = new BitmapFont();
final String text = "Test";
final GlyphLayout layout = new GlyphLayout(font, text);
// or for non final texts: layout.setText(font, text);
final float fontX = objectX + (objectWidth - layout.width) / 2;
final float fontY = objectY + (objectHeight + layout.height) / 2;
font.draw(batch, layout, fontX, fontY);
Outdated example:
This no longer works!
If you do not want to use it, you can get the font width and height with:
font.getBounds("Test text");
So you can do something like this:
String fontText = "";
fontX = buttonX + buttonWidth/2 - font.getBounds(fontText).width/2;
fontY = buttonY + buttonHeight/2 + font.getBounds(fontText).height/2;
For the newer version of libgdx the function BitMapFont.getBounds() isn't there in api anymore. You can use GlyphLayout to get bounds.For example,
BitmapFont font;
SpriteBatch spriteBatch;
//... Load any font of your choice first
FreeTypeFontGenerator fontGenerator = new FreeTypeFontGenerator(
Gdx.files.internal("myFont.ttf")
);
FreeTypeFontGenerator.FreeTypeFontParameter freeTypeFontParameter =
new FreeTypeFontGenerator.FreeTypeFontParameter();
freeTypeFontParameter.size = size;
fontGenerator.generateData(freeTypeFontParameter);
font = fontGenerator.generateFont(freeTypeFontParameter);
//Initialize the spriteBatch as requirement
GlyphLayout glyphLayout = new GlyphLayout();
String item = "Example";
glyphLayout.setText(font,item);
float w = glyphLayout.width;
font.draw(spriteBatch, glyphLayout, (Game.SCREEN_WIDTH - w)/2, y);
Try the following:
label.setPosition(Gdx.graphics.getWidth()/2-(label.getPrefWidth()/2),Gdx.graphics.getHeight()-(label.getPrefHeight()/2));

How can i run my java application for virtual screens?

In Linux, we have virtual screens like desktop 1, 2, 3, 4. Most cases we use desktop 1 (screen 1, with one monitor).
Now, my question is how can i tell my java application to launch on desktop 2 (screen 2, with one monitor)
By default when i run java -cp /var/tmp/SystemX.jar run.X it will launch in desktop 1, screen 1. Which is not my case.
Tried: following but did not helped cause, it runs for dual monitor scenario. Not what i am expecting.
screen = Toolkit.getDefaultToolkit().getScreenSize();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] screenDevices = ge.getScreenDevices();
for (int i = 0; i < screenDevices.length; i++) {
System.out.println(screenDevices[i].getIDstring());
int screenWidth = 1024;
int screenHeight = 764;
if (screenDevices[i].getDisplayMode()!=null) {
DisplayMode dm = screenDevices[i].getDisplayMode();
screenWidth = dm.getWidth();
screenHeight = dm.getHeight();
}
System.out.println("[myResolution]: " + screenWidth + " " + screenHeight);
screen.width = screenWidth;
screen.height = screenHeight;
}
Follow up:
#!/bin/sh
(export DISPLAY=:0.0 && java -cp /var/tmp/SystemX.jar run.X) & (wmctrl -r "WINDOW_TITLE" -t DESKTOP_NUMBER)
* But what if my application is border less, when it has no window title ? how do i tell wmctrl ?
The borderless applications should still have window titles. (ie. xfce4-panel shows.) You can check what they are by using:
wmctrl -l
From the command line. If you're having a hard time figuring out which window is yours, try the command before you open it, then once it's open. That way, you can just look for the new window.

How to display frame only when required & set frame to appear on top all the time?

My program will alert users when data (stock name & price) in the database matches with the data (stock name and price) from Yahoo Finance. With the help of HarryJoy i'm able to implement a pop up notification.
Problem is the pop up location on the screen is based on the database loop (int db). The frame will pop even if data doesn't match.
How can I set a counter or some method to pop up the frame only when database data = Yahoo Finance data? Also, my notification panels appears to be behind the main frame. How can make the panels appear on top of my main frame?
I hope I've given enough information, please ask if still unclear. Any guidance will be appreciated! Thanks!
In the database (using code sample only to display my explanation in order, source code below).
Object 1 = match
Object 2 = doesn't match (hence there's a gap)
Object 3 = match
Object 4 = match
Screenshot:
Code:
for (int db=0; db<= rowCount; db++)
{
Object popSymbol = table.getModel().getValueAt(db, 0);
String popupSymbol = popSymbol.toString();
Object popValue = table.getModel().getValueAt(db, 1);
String str = popValue.toString();
double popStockValue = Double.valueOf(str).doubleValue();
String stockNameDB = popupSymbol;
StockPara stock = YahooStock.getInstance().getStockPrice(stockNameDB);
double stockPriceDB = Math.round(stock.getPrice());
final JFrame popUpFrame;
final JPanel popupPanel;
if (stockPriceDB == popStockValue)
{
String header = "Stock: " + stock.getTicker() + " is now # " + stock.getPrice();
String message = "";
popUpFrame = new JFrame();
popUpFrame.setSize(320,90);
popUpFrame.setUndecorated(true);
popUpFrame.getContentPane().setLayout(null);
popupPanel = new JPanel();
popupPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
popupPanel.setBounds(0, 0, 320, 90);
getContentPane().add(popupPanel);
popupPanel.setBackground(new Color(255, 255, 224));
popupPanel.setLayout(null);
popUpFrame.add(popupPanel);
// Other labels, images, etc.
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Insets toolHeight = Toolkit.getDefaultToolkit().getScreenInsets(popUpFrame.getGraphicsConfiguration());
popUpFrame.setLocation(screenSize.width - popUpFrame.getWidth(), screenSize.height - toolHeight.bottom - (popUpFrame.getHeight() * (db+1)));
}
}
To solve your issue quickly, simply create an additional counter (int counter = 0;). Then use that counter instead of db to position your popUpFrame and right after that increment counter.
int counter = 0; // Initiate outside de loop
...
for(int db=0; db<= rowCount; db++) {
...
if (stockPriceDB == popStockValue) {
...
popUpFrame.setLocation(screenSize.width - popUpFrame.getWidth(),
screenSize.height - toolHeight.bottom - (popUpFrame.getHeight() * (counter+1)));
counter++;
}
}
To bring your frame to the front use:
popUpFrame.toFront()
and to force it to be always on top (although I would really not recommend that because it is more annoying for the user than anything else):
popUpFrame.setAlwaysOnTop(true);
This is not necessarily supported by all platforms.
for on top issue, use
notificationPanel.requestFocus();

Categories