i can't seem to find online help on how to add different type of borders in Eclipse RCP. I know Swing has BevelBorder which can be achieved using BorderFactory. Any swt equivalence?
Try this styles: SWT.SHADOW_IN, SWT.SHADOW_OUT, SWT.SHADOW_ETCHED_IN, SWT.SHADOW_ETCHED_OUT
Please use this method for Bevel Border
private void drawBorders(GC gc, int x, int y, int w, int h) {
final Display disp = getDisplay();
final Color topleft = disp.getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
final Color bottomright = disp.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
if (topleft != null && bottomright != null) {
gc.setLineWidth(1);
gc.setForeground(bottomright);
gc.drawLine(x + w, y, x + w, y + h);
gc.drawLine(x, y + h, x + w, y + h);
gc.setForeground(topleft);
gc.drawLine(x, y, x + w - 1, y);
gc.drawLine(x, y, x, y + h - 1);
}
}
Related
There is no context2d.ellipse in GWT, so how can I draw an ellipse? The underlying HTML5 canvas supports it, so I thought I would try and access that using a native method using the following (but it does not work)...
ellipse(context.getCanvas(),(double)x,(double)y,50.,80.,0.,0.,Math.PI*2);
...
public final native void ellipse(CanvasElement e, double x, double y, double rx, double ry, double ro, double sa, double ea)
/*-{
e.getContext("2d").ellipse(x, y, rx, ry, ro, sa, ea, false);
}-*/;
ideas / solutions?
If there is no implementation you can draw it using lines, just needs a bit of trigonometry...
function drawEllipse(x, y, rx, ry) {
ctx.beginPath();
for (i = 0; i <= 360; i++) {
a = i * Math.PI / 180
px = rx * Math.sin(a) + x
py = ry * Math.cos(a) + y
ctx.lineTo(px, py);
}
ctx.stroke();
}
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
drawEllipse(100, 100, 90, 30);
drawEllipse(100, 100, 50, 90);
drawEllipse(100, 100, 50, 25);
<canvas id=canvas width=200 height=200></canvas>
I faced the problem in my Flutter app that I can't draw this kind of a shape for my Slider
What I have now is:
final paint = Paint()
..color = Colors.black
..style = PaintingStyle.fill;
final rect = Rect.fromCircle(center: center, radius: thumbRadius);
final rrect = RRect.fromRectAndRadius(
Rect.fromPoints(
Offset(rect.left - 5, rect.top),
Offset(rect.right + 5, rect.bottom),
),
Radius.circular(thumbRadius + 2),
);
canvas.drawRRect(rrect, paint);
Also, it would be great to change height of all bar, because next code changes only the size after player
SliderTheme(
data: SliderThemeData(
trackHeight: 2,
thumbShape: CustomSliderPlayer(),
),
child: Slider(...)
From the comments it looks like you are not familiar with quadratic bezier curves, they are very simple, I would recommend you to start on a Javascript canvas, they are easier to test that way and logic is the same, we move to the starting point then we draw the curve, see sample snippet below
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function dobleQuad(x, y, w, h) {
ctx.beginPath();
ctx.moveTo(x - w, y);
ctx.quadraticCurveTo(x, y - h, x + w, y);
ctx.moveTo(x - w, y);
ctx.quadraticCurveTo(x, y + h, x + w, y);
ctx.fill();
}
function drawSlider(x, y) {
ctx.moveTo(0, y - 2);
ctx.fillRect(0, y - 2, canvas.width, 4);
dobleQuad(x, y, 20, 22)
}
drawSlider(50, 50)
canvas.addEventListener('mousemove', function(evt) {
ctx.clearRect(0, 0, canvas.width, canvas.height)
var rect = canvas.getBoundingClientRect();
drawSlider( evt.clientX - rect.left, 50 )
})
<canvas id="canvas"></canvas>
Just keep in mind that in JS it's quadraticCurveTo but in flutter quadraticBezierTo
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/quadraticCurveTo
void ctx.quadraticCurveTo(cpx, cpy, x, y);
cpx, cpy
The coordinates of the control point.
x, y
The coordinates of the end point.
https://api.flutter.dev/flutter/dart-ui/Path/quadraticBezierTo.html
void quadraticBezierTo(
double x1, double y1,
double x2, double y2
)
Adds a quadratic bezier segment that curves from the current point
to the given point (x2,y2), using the control point (x1,y1).
When I plot point1(p1) and point2(p2), the line between p1 and p2 is drawn. I wanna know a set of the points making the line.
For example, I wanna get x, y coordinates (as array type: x[], y[]). Is there any algorithms or code?
Here's what I have come up with:
It is fair to say that we need to use the slope formula, y = m*x + b to find the slope so we can plot our points along that line. We need the following:
(x1, y1)
(x2, y2)
to find the following:
m = (y2 - y1) / (x2 - x1)
b = y1 - (m * x1)
minX = min(x1, x2) used for limiting our lower bound
maxX = max(x1, x2) used for limiting our upper bound
Now that everything is set, we can plot our line pixel by pixel and obtain all (x,y) coordinates we need. The logic is simple:
let x loop from minX to maxX and plug it in y = m*x + b (we already have all the variables except y). Then, store the (x,y) pair.
I have used Java for coding this logically and visually. Also, I used LinkedList instead of arrays (because I we can't know the number of points we will obtain).
I have also drawn what Java would draw (in blue) and my approach (in red). They are almost perfectly the exact output and coordinates. The image below is zoomed 5x the original size.
Note! The above explanation is what you would use if the line is not vertical (because the slope would be undefined, division by zero). If it is, then you will plug y (instead of x) values and find the x (instead of y) value from the following formula x = (y - b) / m (instead of y = m*x + b). Though, the code takes care of vertical lines.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.LinkedList;
import javax.swing.JFrame;
public class LineDrawing extends Canvas {
int x1 = 5;
int y1 = 10;
int x2 = 105;
int y2 = 100;
double m = ((double) (y2 - y1)) / ((double) (x2 - x1));//slope
double b = y1 - (m * ((double) x1));//vertical shift
//Takes care of the domain we will loop between.
//min and max will be assigned minX and maxX if the line is not vertical.
//minY and maxY are assigned to min and max otherwise.
int minX = Math.min(x1, x2);//minimum x value we should consider
int maxX = Math.max(x1, x2);//maximum x value we should consider
int minY = Math.min(y1, y2);//minimum y value we should consider
int maxY = Math.max(y1, y2);//maximum y value we should consider
int min = 0;
int max = 0;
boolean plugX = true;//if true, the line is not vertical.
LinkedList<Point> points = new LinkedList<>();//Store all points here
public LineDrawing() {
if (x1 == x2) {//plug the y value instead the x, this is a vertical line.
plugX = false;
min = minY;
max = maxY;
} else {//dont change and plug x values.
min = minX;
max = maxX;
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
//Draw the line, using default java drawLine in blue.
g.setColor(Color.BLUE);
g.drawLine(x1, y1, x2, y2);
//change the color to red, it will draw our verison.
g.setColor(Color.RED);
//Draw the points, point by point on screen.
//Plug m, x, and b in the formula y = m*x + b
//to obtain the y value.
//OR
//Plug m, y, and b in the formula x = (y - b) / m
//to obtain the x value if vertical line.
//Then plot (x,y) coordinate on screen and add the point to our linkedList.
for (int i = min; i <= max; i++) {
int obtained = 0;
if (plugX) {//not a vertical line
obtained = (int) Math.round((m * i + b));
System.out.println("x = " + i + " , y = " + obtained);
points.add(new Point(i, obtained));
//Uncomment to see the full blue line.
g.drawLine(i, obtained, i, obtained);
} else {//vertical line
obtained = (int) Math.round((double) (i - b) / (double) m);
System.out.println("x = " + x1 + " , y = " + i);
g.drawLine(x1, i, x1, i);//Uncomment to see the full blue line.
points.add(new Point(x1, i));
}
}
//Print out the number of points as well as the coordinates themselves.
System.out.println("Total points: " + points.size());
for (int i = 0; i < points.size(); i++) {
System.out.println(i + " ( " + points.get(i).x
+ ", " + points.get(i).y + " )");
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(120, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LineDrawing());
frame.setVisible(true);
}
}
I am working on pdf using iTextSharp and product owner decided to have a "stickers" alike text boxes casting a shadow on background for it. I was searching the Internet and couldn't find a hint to how to achieve this effect. The design provided for it is as follows:
Could anybody more experienced with iText or iTextsharp help me by advising on how to achieve such effect please?
Kind regards
Karol
Using the hints and links in Joris' answer, one can easily implement a helper method like this to draw the shaded rounded rectangles:
void DrawRoundedShadedRectangle(PdfWriter writer, float x, float y, float w, float h, float r, float shade, BaseColor innerColor, BaseColor shadeColor, BaseColor outerColor)
{
PdfContentByte canvas = writer.DirectContent;
canvas.SaveState();
canvas.Rectangle(x - shade, y + r, w + 2 * shade, h - 2*r);
canvas.Clip();
canvas.NewPath();
PdfShading shadingRight = PdfShading.SimpleAxial(writer, x + w, y, x + w + shade, y, shadeColor, outerColor, false, false);
canvas.PaintShading(shadingRight);
PdfShading shadingLeft = PdfShading.SimpleAxial(writer, x, y, x - shade, y, shadeColor, outerColor, false, false);
canvas.PaintShading(shadingLeft);
canvas.RestoreState();
canvas.SaveState();
canvas.Rectangle(x + r, y - shade, w - 2 * r, h + 2 * shade);
canvas.Clip();
canvas.NewPath();
PdfShading shadingTop = PdfShading.SimpleAxial(writer, x, y + h, x, y + h + shade, shadeColor, outerColor, false, false);
canvas.PaintShading(shadingTop);
PdfShading shadingBottom = PdfShading.SimpleAxial(writer, x, y, x, y - shade, shadeColor, outerColor, false, false);
canvas.PaintShading(shadingBottom);
canvas.RestoreState();
canvas.SaveState();
canvas.Rectangle(x + w - r, y + h - r, r + shade, r + shade);
canvas.Clip();
canvas.NewPath();
PdfShading shadingTopRight = PdfShading.SimpleRadial(writer, x + w - r, y + h - r, r, x + w - r, y + h - r, r + shade, shadeColor, outerColor);
canvas.PaintShading(shadingTopRight);
canvas.RestoreState();
canvas.SaveState();
canvas.Rectangle(x - shade, y + h - r, r + shade, r + shade);
canvas.Clip();
canvas.NewPath();
PdfShading shadingTopLeft = PdfShading.SimpleRadial(writer, x + r, y + h - r, r, x + r, y + h - r, r + shade, shadeColor, outerColor);
canvas.PaintShading(shadingTopLeft);
canvas.RestoreState();
canvas.SaveState();
canvas.Rectangle(x - shade, y - shade, r + shade, r + shade);
canvas.Clip();
canvas.NewPath();
PdfShading shadingBottomLeft = PdfShading.SimpleRadial(writer, x + r, y + r, r, x + r, y + r, r + shade, shadeColor, outerColor);
canvas.PaintShading(shadingBottomLeft);
canvas.RestoreState();
canvas.SaveState();
canvas.Rectangle(x + w - r, y - shade, r + shade, r + shade);
canvas.Clip();
canvas.NewPath();
PdfShading shadingBottomRight = PdfShading.SimpleRadial(writer, x + w - r, y + r, r, x + w - r, y + r, r + shade, shadeColor, outerColor);
canvas.PaintShading(shadingBottomRight);
canvas.RestoreState();
canvas.SaveState();
canvas.SetColorFill(innerColor);
canvas.SetColorStroke(innerColor);
canvas.RoundRectangle(x, y, w, h, r);
canvas.FillStroke();
canvas.RestoreState();
}
For example,
DrawRoundedShadedRectangle(writer, 100, 500, 200, 100, 10, 20, BaseColor.GREEN, BaseColor.RED, BaseColor.WHITE);
draws this:
And this code
DrawRoundedShadedRectangle(writer, writer.PageSize.GetLeft(100), 300, writer.PageSize.Width - 200, 100, 10, 10, BaseColor.ORANGE, BaseColor.YELLOW, BaseColor.WHITE);
PdfContentByte canvas = writer.DirectContent;
canvas.SaveState();
canvas.Rectangle(writer.PageSize.Left, writer.PageSize.Bottom, writer.PageSize.Right, 300);
canvas.Clip();
canvas.NewPath();
DrawRoundedShadedRectangle(writer, writer.PageSize.GetLeft(100), 100, writer.PageSize.Width - 200, 200, 10, 10, BaseColor.WHITE, BaseColor.YELLOW, BaseColor.WHITE);
canvas.RestoreState();
draws this
By tweaking the radius, the shade, and all the color parameters this should become very similar to the provided design.
This can be done with iText.
It's a matter of using drawing operations on the canvas to achieve the effect.
in your case
- a rounded rectangle, filled with orange
- a rounded rectangle underneath it, filled with white
I'm making application with huge mass of 3D shapes and I need them fully transparent and with border. I tried find any way to apply border to Shape3D, specifically to Box and Sphere but I can't find anything. So my questions are:
Is there any way how to add border to Shape3D?
If yes, how to do it?
No, there is no option to add borders to 3d shapes, but you can use very thin cyllinders instead (only works for boxes though):
public void createBoxLines(double contW, double contH, double contD, double x, double y, double z) {
//You call this method to create a box with a size and location you put in
//This method calls the createLine method for all the sides of your rectangle
Point3D p1 = new Point3D(x, y, z);
Point3D p2 = new Point3D(contW + x, y, z);
Point3D p3 = new Point3D(x, contH + y, z);
Point3D p4 = new Point3D(contW + x, contH + y, z);
createLine(p1, p2);
createLine(p1, p3);
createLine(p3, p4);
createLine(p2, p4);
Point3D p5 = new Point3D(x, y, contD + z);
Point3D p6 = new Point3D(contW + x, y, contD + z);
Point3D p7 = new Point3D(x, contH + y, contD + z);
Point3D p8 = new Point3D(contW + x, contH + y, contD + z);
createLine(p5, p6);
createLine(p5, p7);
createLine(p7, p8);
createLine(p6, p8);
createLine(p1, p5);
createLine(p2, p6);
createLine(p3, p7);
createLine(p4, p8);
}
double strokewidth = 1;
public void createLine(Point3D origin, Point3D target) {
//creates a line from one point3d to another
Point3D yAxis = new Point3D(0, 1, 0);
Point3D diff = target.subtract(origin);
double height = diff.magnitude();
Point3D mid = target.midpoint(origin);
Translate moveToMidpoint = new Translate(mid.getX(), mid.getY(), mid.getZ());
Point3D axisOfRotation = diff.crossProduct(yAxis);
double angle = Math.acos(diff.normalize().dotProduct(yAxis));
Rotate rotateAroundCenter = new Rotate(-Math.toDegrees(angle), axisOfRotation);
Cylinder line = new Cylinder(strokewidth, height);
line.getTransforms().addAll(moveToMidpoint, rotateAroundCenter);
myGroup.getChildren().add(line);
}
The createLine method can be used seperately to make lines between different points.
I cant provide many comments for that method, because I basically copied it from some blog. Although I'm having a hard time finding that blog again.
Thanks Alex Quilliam thanks for the code i was able to improve my program.
https://i.imgur.com/HY2x9vF.png
Cylinder line = new Cylinder(strokewidth, height);
↓
Box line = new Box(strokewidth, height, strokewidth);
JavaFX_3D_Cube_Outline_Test