代码比较简单,但初次接触javafx,会不知道从哪里下手,多与其他人交流看看代码能让我们事半功倍。代码内容我就不多做解释,自己有个思路知道有哪些函数该怎么下手就好。
效果:
一共就只有三个文件,其中fxml文件主要是利用javafx scene builder完成的。
//Painter.java
package p3;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Painter extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root =
FXMLLoader.load(getClass().getResource("Painter.fxml"));
Scene scene = new Scene(root);
stage.setTitle("Painter"); // displayed in window's title bar
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
//PainterController.java
package p3;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
public class PainterController {
// enum representing pen sizes
private enum PenSize {
SMALL(2), MEDIUM(4), LARGE(6);
private final int radius;
PenSize(int radius) {
this.radius = radius;
}
public int getRadius() {
return radius;
}
};
private enum Shape {
RECT, CIRCLE, LINE
};
// RGB三元色
private int red = 0;
private int green = 0;
private int blue = 0;
// 初始化:粗细、颜色、形状
private PenSize radius = PenSize.MEDIUM;
private Paint brushColor = Color.BLACK;
private Paint TRANSPARENT = Color.rgb(255,255,255,0.0);//透明色
private Shape shape = Shape.LINE;
//鼠标坐标
private double mouseEnterX;
private double mouseEnterY;
private double mouseReleasedX;
private double mouseReleasedY;
private double rectangleWidth;
private double rectangleHeight;
private double circleCenterX;
private double circleCenterY;
private double circleRadius;
@FXML
private Button setColorButton;
@FXML
private RadioButton mediumRadioButton;
@FXML
private TextField greenTextField;
@FXML
private ToggleGroup sizeToggleGroup;
@FXML
private ToggleGroup shapeToggleGroup;
@FXML
private TextField redTextField;
@FXML
private RadioButton lineRadioButton;
@FXML
private RadioButton rectRadioButton;
@FXML
private Pane drawingAreaPane;
@FXML
private Button clearButton;
@FXML
private RadioButton largeRadioButton;
@FXML
private RadioButton smallRadioButton;
@FXML
private TextField blueTextField;
@FXML
private Button undoButton;
@FXML
private RadioButton circleRadioButton;
public void initialize() {
//形状按钮赋值
lineRadioButton.setUserData(Shape.LINE);
circleRadioButton.setUserData(Shape.CIRCLE);
rectRadioButton.setUserData(Shape.RECT);
//粗细按钮赋值
smallRadioButton.setUserData(PenSize.SMALL);
mediumRadioButton.setUserData(PenSize.MEDIUM);
largeRadioButton.setUserData(PenSize.LARGE);
}
void getValueOfRgb() {
red = Integer.parseInt(redTextField.getText());
green = Integer.parseInt(greenTextField.getText());
blue = Integer.parseInt(blueTextField.getText());
brushColor = Color.rgb(red, green, blue);
}
@FXML
void drawingAreaMousePressed(MouseEvent e) {
mouseEnterX = e.getX();
mouseEnterY = e.getY();
if(mouseEnterX > drawingAreaPane.getWidth() || mouseEnterY > drawingAreaPane.getHeight())
return;
}
@FXML
void drawingAreaMouseReleased(MouseEvent e) {
mouseReleasedX=e.getX();
mouseReleasedY=e.getY();
if(mouseReleasedX > drawingAreaPane.getWidth() || mouseReleasedX < 0 || mouseReleasedY > drawingAreaPane.getHeight()|| mouseReleasedY <0)
return;
getValueOfRgb();
switch (shape) {
case LINE:
Line newLine = new Line(mouseEnterX, mouseEnterY, mouseReleasedX, mouseReleasedY);
newLine.setStroke(brushColor);
newLine.setStrokeWidth(radius.getRadius());
drawingAreaPane.getChildren().add(newLine);
break;
case RECT:
rectangleWidth = Math.abs(mouseReleasedX - mouseEnterX);
rectangleHeight = Math.abs(mouseReleasedY - mouseEnterY);
if(mouseEnterX > mouseReleasedX)
mouseEnterX = mouseReleasedX;
if(mouseEnterY > mouseReleasedY)
mouseEnterY = mouseReleasedY;
Rectangle newRect = new Rectangle(mouseEnterX, mouseEnterY, rectangleWidth, rectangleHeight);
newRect.setStroke(brushColor);
newRect.setFill(TRANSPARENT);
newRect.setStrokeWidth(radius.getRadius());
drawingAreaPane.getChildren().add(newRect);
break;
case CIRCLE:
circleCenterX = (mouseEnterX + mouseReleasedX) / 2;
circleCenterY = (mouseEnterY + mouseReleasedY) /2;
circleRadius = Math.hypot((circleCenterX - mouseEnterX), (circleCenterY - mouseEnterY));
Circle newCircle = new Circle(circleCenterX,circleCenterY,circleRadius);
newCircle.setStroke(brushColor);
newCircle.setFill(TRANSPARENT);
newCircle.setStrokeWidth(radius.getRadius());
drawingAreaPane.getChildren().add(newCircle);
break;
}
}
@FXML
void sizeRadioButtonSelected(ActionEvent event) {
radius = (PenSize) sizeToggleGroup.getSelectedToggle().getUserData();
}
@FXML
void shapeRadioButtonSelected(ActionEvent event) {
shape = (Shape) shapeToggleGroup.getSelectedToggle().getUserData();
//shapeRadioButtonSelected
}
@FXML
void undoButtonPressed(ActionEvent event) {
int count = drawingAreaPane.getChildren().size();
// if there are any shapes remove the last one added
if (count > 0) {
drawingAreaPane.getChildren().remove(count - 1);
}
}
@FXML
void clearButtonPressed(ActionEvent event) {
drawingAreaPane.getChildren().clear(); // clear the canvas
}
}
Painter.fxml我是使用scene builder完成的
<!--Painter.fxml-->
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.control.ToggleGroup?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<BorderPane prefHeight="530.0" prefWidth="650.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="p3.PainterController">
<left>
<VBox maxHeight="1.7976931348623157E308" prefHeight="464.0" prefWidth="106.0" spacing="8.0" BorderPane.alignment="CENTER">
<children>
<TitledPane text="粗细">
<content>
<VBox spacing="8.0">
<children>
<RadioButton fx:id="smallRadioButton" mnemonicParsing="false" onAction="#sizeRadioButtonSelected" text="细">
<toggleGroup>
<ToggleGroup fx:id="sizeToggleGroup" />
</toggleGroup>
</RadioButton>
<RadioButton fx:id="mediumRadioButton" mnemonicParsing="false" onAction="#sizeRadioButtonSelected" selected="true" text="中等" toggleGroup="$sizeToggleGroup" />
<RadioButton fx:id="largeRadioButton" mnemonicParsing="false" onAction="#sizeRadioButtonSelected" text="粗" toggleGroup="$sizeToggleGroup" />
</children>
</VBox>
</content>
</TitledPane>
<TitledPane text="形状">
<content>
<VBox spacing="8.0">
<children>
<RadioButton fx:id="lineRadioButton" mnemonicParsing="false" onAction="#shapeRadioButtonSelected" selected="true" text="直线">
<toggleGroup>
<ToggleGroup fx:id="shapeToggleGroup" />
</toggleGroup></RadioButton>
<RadioButton fx:id="rectRadioButton" mnemonicParsing="false" onAction="#shapeRadioButtonSelected" text="矩形" toggleGroup="$shapeToggleGroup" />
<RadioButton fx:id="circleRadioButton" mnemonicParsing="false" onAction="#shapeRadioButtonSelected" text="圆形" toggleGroup="$shapeToggleGroup" />
</children>
</VBox>
</content>
</TitledPane>
<TitledPane text="颜色">
<content>
<VBox spacing="8.0">
<children>
<GridPane alignment="CENTER_LEFT" prefHeight="90.0" prefWidth="84.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="95.0" minWidth="10.0" prefWidth="37.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="171.0" minWidth="10.0" prefWidth="43.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label alignment="CENTER_RIGHT" contentDisplay="CENTER" prefHeight="24.0" prefWidth="40.0" text="红:">
<font>
<Font size="18.0" />
</font>
</Label>
<Label alignment="CENTER_RIGHT" prefHeight="20.0" prefWidth="64.0" text="绿:" GridPane.rowIndex="1">
<font>
<Font size="18.0" />
</font>
</Label>
<Label alignment="CENTER_RIGHT" prefHeight="24.0" prefWidth="52.0" text="蓝:" GridPane.rowIndex="2">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="redTextField" alignment="CENTER" text="0" GridPane.columnIndex="1" />
<TextField fx:id="greenTextField" alignment="CENTER" text="0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<TextField fx:id="blueTextField" alignment="CENTER" text="0" GridPane.columnIndex="1" GridPane.rowIndex="2" />
</children>
</GridPane>
</children>
</VBox>
</content>
</TitledPane>
<Button fx:id="undoButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#undoButtonPressed" text="上一步" />
<Button fx:id="clearButton" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#clearButtonPressed" text="清空" />
</children>
<BorderPane.margin>
<Insets right="8.0" />
</BorderPane.margin>
</VBox>
</left>
<center>
<Pane fx:id="drawingAreaPane" onMousePressed="#drawingAreaMousePressed" onMouseReleased="#drawingAreaMouseReleased" prefHeight="513.0" prefWidth="520.0" style="-fx-background-color: white;" BorderPane.alignment="CENTER" />
</center>
<padding>
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />
</padding>
</BorderPane>
由于本人水平有限,代码存在错误之处欢迎指正。