Home > database >  Painting shapes in JavaFX
Painting shapes in JavaFX

Time:09-27

I created a simple paint program which allows the user to choose between 4 shapes(line,circle,rectangle,ellipse) , the user can change the width height and stroke width , he can save the design he makes , undo and redo , the user can also choose the stroke type (solid or dashed) , I'm facing one problem , when the user picks dashed as the stroke type , I want him to be able to choose the thickness of the stroke , it works perfectly fine with the solid , but with the dashed it's just increasing or decreasing the number of dashed lines , any idea on how I can fix the number of dashed lines and increase the thickness of the dashed lines.

NOTE : I'm using the rectangle shape in the code to make the code small.

Here's the CODE :

import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.imageio.ImageIO;

public class GFG extends Application {

@Override
public void start(Stage primaryStage) {

Image image2 = new 
Image("C:\\Users\\Mhamd\\Desktop\\laol\\src\\resources\\pngegg.png",100,100,false,false);
    ImageView view2 = new ImageView(image2);
    view2.setFitHeight(40);
    view2.setPreserveRatio(true);
ToggleButton rectbtn = new ToggleButton();
rectbtn.setGraphic(view2);
ToggleButton[] toolsArr = {rectbtn};

    ToggleGroup tools = new ToggleGroup();

    for (ToggleButton tool : toolsArr) {
        tool.setMinWidth(50);
        tool.setToggleGroup(tools);
        tool.setCursor(Cursor.HAND);
    }
ColorPicker cpLine = new ColorPicker(Color.BLACK);
    ColorPicker cpFill = new ColorPicker(Color.TRANSPARENT);

    TextField textWidth = new TextField("32");
    TextField textHeight = new TextField("32");
    TextField contouring = new TextField("2");
Label line_color = new Label("Line Color");
    Label fill_color = new Label("Fill Color");
    Label line_width = new Label("3.0");
    Label imgWidth = new Label("Width");
    Label imgHeight = new Label("Height");
String week_days[] =
            { "Solid", "Dotted"};
    ChoiceBox choiceBox = new ChoiceBox(FXCollections
            .observableArrayList(week_days));
VBox btns = new VBox(10);
    btns.getChildren().addAll(imgWidth,textWidth,imgHeight,textHeight, line_color, cpLine, 
fill_color, cpFill, line_width, contouring,choiceBox);
    btns.setPadding(new Insets(5));
    btns.setStyle("-fx-background-color: #999");
    btns.setPrefWidth(100);
Canvas canvas = new Canvas(1080, 790);
    GraphicsContext gc;
    gc = canvas.getGraphicsContext2D();
    gc.setLineWidth(1);
Rectangle rect = new Rectangle();
canvas.setOnMouseClicked(e->{
        if(rectbtn.isSelected()){
            double widthSize = Double.parseDouble(textWidth.getText());
            double heightSize = Double.parseDouble(textHeight.getText());
            double strokeWidth = Double.parseDouble(contouring.getText());
            gc.setStroke(cpLine.getValue());
            if(choiceBox.getSelectionModel().isSelected(0)){
                gc.setLineWidth(strokeWidth);
            }
            else if(choiceBox.getSelectionModel().isSelected(1)){
                //gc.setLineDashes(strokeWidth);
                gc.setLineDashOffset(10);
            }
            gc.setFill(cpFill.getValue());
            rect.setX(e.getX() - 20);
            rect.setY(e.getY() - 20);
            rect.setWidth(widthSize);
            rect.setHeight(heightSize);
            gc.fillRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
            gc.strokeRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
            undoHistory.push(new Rectangle(rect.getX(), rect.getY(), rect.getWidth(), 
rect.getHeight()));
        }
public static void main(String[] args) {
    launch(args);
}
}

CodePudding user response:

You have to set a width for the dashed line too. Setting line dashes to the line width does not make much sense unless you want something that looks more like a dotted line. And you need the dash offset only in specific cases but not in general.

  • Related