I am trying to do the paint on Javafx. I am using a pane and draw an irregular shape using the code below (like using the pencil in the Microsoft Paint). Then I wished to colour the shape. I have no idea how to fill the colour.
The following code is how I draw on the pane.
#FXML
private void drawingAreaMouseDragged(MouseEvent e) {
if(e.getX() > 0 && e.getY() > 0) {
if(isPen) {
if(e.getX() > penSize && e.getY() > penSize) {
Circle newCircle = new Circle(e.getX(), e.getY(), penSize, pForeColor);
group.getChildren().add(newCircle);
}
}
}
What I expecting is something like the following pictures (like the Microsoft Paint). First, draw using pencil and form the irregular shape. Then fill it.
new pane
shape drawn using pencil
fill with colour
Related
Problem description - In my application, I need to get back color of tile pane (or any other control), but i don't find any property/function.
I use tile pane to show color swatches, and on its click event I want its background color.
What I want: I want to get background color of control on its click event
Try this in the ActionEvent you can do this
handle(ActionEvent event){//suppose we are in the handle method
Object o = event.getSource();
if(o instanceof Region){
Background b = ((Region)o).getBackground();
Paint p = b.getFills().get(0).getFill();//paint is actually your color :)
if(p instanceof Color){
((Color)p) //now you have a color :)
Hope it helps
Now that we have Image plots capability in ILNumerics, I am replacing all my code to use ImageSc plots inplace of surface plots.
For surface plots, we can specify X and Y scale values in the form of grid. Is there any way to modify the index based scale values for image plots without overwriting TickCreationFunction?
you could place the plot inside a group and use the group to translate the plot inside the plot cube:
private void ilPanel1_Load(object sender, EventArgs e) {
ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
new ILGroup(translate: new Vector3(-5,10,100)) {
new ILImageSCPlot(ILSpecialData.sincf(10,20))
}
});
}
This would work with any plot object - not only ImageSC.
I have FXML file that has Pane as one of it's entries, used to show graph. It is not not visible by default. When checkbox is checked, the Pane is visible. Now I have to add graph in Pane and show graph when pane is visible. How to achieve this? I have created graph using this link. JavaFX real-time LineChart with time axis
pane.visibleProperty().addListener((obs, wasVisible, isVisible) -> {
if(isVisible) { // pane became visible, add the graph
LineChart<X, Y> chart = ...;
pane.getChildren().add(chart);
} else { // pane became hidden, remove the graph
pane.getChildren().clear();
}
});
I've create simple example: background surface layer and 10 small "dots" on it (10 surface layers 10x10 px each filled with color via fillRect()). Paint method simply moves the dots around periodically:
private SurfaceLayer background;
private List<Layer> dots = new ArrayList<Layer>();
#Override
public void init()
{
background = graphics().createSurfaceLayer(graphics().width(), graphics().height());
background.surface().setFillColor(Color.rgb(100, 100, 100));
background.surface().fillRect(0, 0, graphics().width(), graphics().height());
graphics().rootLayer().add(background);
for (int i = 0; i < 10; i++)
{
SurfaceLayer dot = graphics().createSurfaceLayer(10, 10);
dot.surface().clear();
dot.surface().setFillColor(Color.rgb(250, 250, 250));
dot.surface().fillRect(0, 0, 10, 10);
dot.setDepth(1);
dot.setTranslation(random()*graphics().width(), random()*graphics().height());
dots.add(dot);
graphics().rootLayer().add(dot);
}
}
#Override
public void paint(float alpha)
{
for (Layer dot : dots)
{
if (random() > 0.999)
{
dot.setTranslation(random()*graphics().width(), random()*graphics().height());
}
}
}
Somehow java version draws all dots while html and android version draw only 1.
Manual doesn't clearly say if i should re-draw all these dots in every paint() call. And as far as i understood SurfaceLayer is meant for cases when you do not modify layer on every frame (so same buffer can be reused?), but this doesn't work.
So can you guys help me with correct SurfaceLayer usage? If i just filled a rectangular on SurfaceLayer - would it ramin on this layer forever or should i fill it in each paint call? If yes - is this different from ImmeadiateLayer?
You don't need to redraw a surface layer on every call to paint. As you have shown, you draw it only when preparing it, and the texture into which you've draw will be rendered every frame without further action on your part.
If the Android and HTML backend are not drawing all of your surface layers, there must be a bug. I'll try to reproduce your test and see if it works for me.
One note: creating a giant surface the size of the screen and drawing a solid color into it is a huge waste of texture memory. Just create an ImmediateLayer that calls fillRect() on every frame, which is far more efficient than creating a massive screen-covering texture.
I'm trying to create the following component:
Just for information, the blank space will contain a text control, and I'm creating a component that represents the black corner with the (i) icon and the "promotion" text.
The part I'm having issues with is this component representing the black corner with the diagonal text. The text has to be able to hold 2 lines. And the black corner has to be able to adjust to the text's size.
What's more, the text has a rotation...
I'm having some doubts on how to do this:
Should I have different controls for each text line?
Should I draw the text in the shape (after doing the rotation) or should I just overlap both components? [When I talk about drawing the text in the shape, I mean in the same way as asked in this question]
Is there any way to get the proper size of the triangle shape without doing some extravagant calculations?
And... do you have any "easier" ways to do this ?
A big thanks for any help you can provide :) I'm a little bit lost with this little component :)
Regards.
BS_C3
Edit 1:
The triangle may have 2 sizes: 1 size that will fit 1 line, and another size to fit 2 lines of text.
The text will be sent as a single string, so it will have to be automatically divided in two lines if needed
I was thinking of using graphics to draw the triangle shape and then use a mask to create the rounded corner --> This is because the same component will be used in other places of the application without the rounded corner
Flex is pretty good at updating group components to whatever size thier contents become, updating dynamically on the fly..
for what your suggesting, I'd probably create the "Promotion" group in the corner as a rectangle, rotate it and fit it to the corner like you want, then using a copy of the rounded rect you use as the maing component background, i'd make a mask to cut the "Promotion" component so you don't see the overlap.
Well, I finally wrote the class and this is the result:
public class Corner extends Canvas
{
private var infoIcon:Image;
private var text:Text;
private var triangle:Shape;
private var bgColor:uint;
public function Corner()
{
super();
infoIcon = new Image;
text = new Text;
text.rotation = -45;
text.width = 75;
text.maxHeight = 30;
text.setStyle('color', '0xffffff');
text.setStyle('textAlign', 'center');
text.y = 53;
this.addChild(infoIcon);
this.addChild(text);
triangle = new Shape;
}
public function build(bgColor:uint = 0x61113D):void{
this.bgColor = bgColor;
// info icon data
// set text
text.addEventListener(FlexEvent.UPDATE_COMPLETE, textHandler);
text.text = 'blabla';
text.validateNow();
}
/**
*
*/
private function textHandler(e:FlexEvent):void{
switch(e.type){
case FlexEvent.UPDATE_COMPLETE:
text.removeEventListener(FlexEvent.UPDATE_COMPLETE, textHandler);
drawTriangle();
break;
}
}
/**
*
*/
private function drawTriangle():void{
var h:int = 80;
// check if the text has 1 or 2 lines
if(text.height > 20)
h = 95;
// remove the triangle shape if it exists
if(this.rawChildren.contains(triangle))
this.rawChildren.removeChild(triangle);
// draw triangle
triangle = new Shape;
triangle.graphics.moveTo(0, 0);
triangle.graphics.beginFill(bgColor);
triangle.graphics.lineTo(h, 0);
triangle.graphics.lineTo(0, h);
triangle.graphics.lineTo(0, 0);
triangle.graphics.endFill();
this.rawChildren.addChildAt(triangle,0);
dispatchEvent(new MyEvent(MyEvent.CORNER_UPDATED));
}
...
}