import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.RadioMenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Main extends Application {
// لأننا ننوي وضع الصورة بداخله pane هنا قمنا بإنشاء كائن من الكلاس
// يمثل الصورة التي تظهر في النافذة Image هنا قمنا بإنشاء كائن من الكلاس
Image image = new Image(getClass().getResourceAsStream("/images/javafx-icon.png"));
// في النافذة image لعرض الصورة التي يشير لها الكائن ImageView هنا قمنا بإنشاء كائن من الكلاس
ImageView imageView = new ImageView(image);
// يمثل القائمة التي تظهر عن النقر بزر الفأرة الأيمن فوق الصورة ContextMenu هنا قمنا بإنشاء كائن من الكلاس
ContextMenu contextMenu = new ContextMenu();
// هنا قمنا بإنشاء جميع الكائنات التي سنستخدمها كعناصر بداخل القائمة
MenuItem menuItem1 = new MenuItem("Rotate Right");
MenuItem menuItem2 = new MenuItem("Rotate Left");
CheckMenuItem checkMenuItem = new CheckMenuItem("Show Border");
RadioMenuItem radioMenuItem1 = new RadioMenuItem("Black Border");
RadioMenuItem radioMenuItem2 = new RadioMenuItem("Blue Border");
// radioMenuItem2 و radioMenuItem1 لأننا ننوي وضع الكائنين toggleGroup هنا قمنا بإنشاء كائن من الكلاس
// لاحقاً في مجموعة واحدة لجعل المستخدم قادر على إختيار إحداهما في كل مرة و ليس كلاهما
ToggleGroup toggleGroup = new ToggleGroup();
// الذي يحتوي على الصورة pane هنا قمنا بتعريف دالة خاصة لرسم أو إخفاء حدود الكائن
public void drawBorderOnDemande()
// checkMenuItem إذا كان يوجد على صح على الكائن
if (checkMenuItem.isSelected())
// pane سيتم إظهار حدود لونها أزرق للكائن radioMenuItem1 إذا كان يوجد علامة صح على الكائن
if (radioMenuItem1.isSelected())
pane.setStyle("-fx-border-style: solid; -fx-border-color: black;");
// pane سيتم إظهار حدود لونها أسود للكائن radioMenuItem2 إذا كان يوجد علامة صح على الكائن
pane.setStyle("-fx-border-style: solid; -fx-border-color: blue;");
// pane سيتم إزالة الحدود عن الكائن checkMenuItem إذا لم يكن هناك علامة صح على الكائن
pane.setStyle("-fx-border:none;");
// قابلين للنقر أم لا radioMenuItem2 و radioMenuItem1 هنا قمنا بتعريف دالة خاصة لتحديد ما إذا كان يجب جعل الكائنين
public void autoEnableOrDisableMenuOptions()
// قابلين للنقر radioMenuItem2 و radioMenuItem1 سيتم جعل الكائنين checkMenuItem إذا قام المستخدم بوضع علامة صح على الكائن
if (checkMenuItem.isSelected())
radioMenuItem1.setDisable(false);
radioMenuItem2.setDisable(false);
// غير قابلين للنقر radioMenuItem2 و radioMenuItem1 سيتم جعل الكائنين checkMenuItem إذا قام المستخدم بإزالة علامة الصح عن الكائن
radioMenuItem1.setDisable(true);
radioMenuItem2.setDisable(true);
public void start(Stage stage) {
// في النافذة pane هنا قمنا بتحديد حجم و مكان الكائن
pane.setPrefSize(202, 202);
// pane في الكائن imageView هنا قمنا بوضع الكائن
pane.getChildren().add(imageView);
// للأننا وضعناه بداخله pane بالنسبة للكائن imageView هنا قمنا بتحديد حجم و مكان الكائن
imageView.setFitWidth(200);
imageView.setFitHeight(200);
imageView.setTranslateX(1);
imageView.setTranslateY(1);
// و هكذا أصبح يمكن إختيار واحد منهم فقط في كل مرة radioMenuItem2 و radioMenuItem1 و ربطنا فيه الكائنين ToggleGroup هنا قمنا بإنشاء كائن من الكلاس
radioMenuItem1.setToggleGroup(toggleGroup);
radioMenuItem2.setToggleGroup(toggleGroup);
// هنا قمنا بوضع كل جميع الكائنات التي أنشأناها خصيصاً لوضعها كعناصر في القائمة بداخلها
contextMenu.getItems().add(menuItem1);
contextMenu.getItems().add(menuItem2);
contextMenu.getItems().add(new SeparatorMenuItem());
contextMenu.getItems().add(checkMenuItem);
contextMenu.getItems().add(new SeparatorMenuItem());
contextMenu.getItems().add(radioMenuItem1);
contextMenu.getItems().add(radioMenuItem2);
// في النافذة Root Node لأننا ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
Group root = new Group();
// root في الكائن datePicker هنا قمنا بإضافة الكائن
root.getChildren().add(pane);
// فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
Scene scene = new Scene(root, 400, 250);
// هنا وضعنا عنوان للنافذة
stage.setTitle("JavaFX ContextMenu");
// أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
// هنا قمنا بإظهار النافذة
// الذي يمثل الصورة imageView هنا قمنا بتحديد ماذا سيحدث عند النقر بواسطة الفأرة على الكائن
imageView.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> {
// في المكان الذي تم النقر عليه (contextMenu) إذا تم النقر على الصورة من الفأرة بواسطة الزر الأيمن, سيتم إظهار القائمة
if (e.getButton() == MouseButton.SECONDARY) {
contextMenu.show(imageView, e.getScreenX(), e.getScreenY());
// menuItem1 هنا قمنا بتحديد ماذا سيحدث عند النقر على الخيار الذي يمثل الكائن
menuItem1.setOnAction((ActionEvent) -> {
// سيتم جعل الصورة تدور 90 درجة باتجاه اليمين
imageView.setRotate(imageView.getRotate() + 90);
// menuItem2 هنا قمنا بتحديد ماذا سيحدث عند النقر على الخيار الذي يمثل الكائن
menuItem2.setOnAction((ActionEvent) -> {
// سيتم جعل الصورة تدور 90 درجة باتجاه اليسار
imageView.setRotate(imageView.getRotate() - 90);
// checkMenuItem هنا قمنا بتحديد ماذا سيحدث عند النقر على الخيار الذي يمثل الكائن
checkMenuItem.setOnAction((ActionEvent) -> {
// لتحديد ما إذا كان يجب رسم حدود حول الصورة أم لا autoEnableOrDisableMenuOptions() و drawBorderOnDemande() سيتم إستدعاء الدالتين
// أم لا radioMenuItem2 و radioMenuItem1 و كيف يجب أن يتم تلوين هذه الحدود و لتحديد ما إذا كان يمكن النقر على الكائنين
autoEnableOrDisableMenuOptions();
// group تابع للمجموعة RadioButton هنا قمنا بتحديد ماذا سيحدث عند النقر على أي
toggleGroup.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> ov, Toggle toggle, Toggle new_toggle) -> {
// غير مختار عند تشغيل التطبيق, أي لا يوجد عليه علامة صح checkMenuItem هنا قمنا بجعل الكائن
checkMenuItem.setSelected(false);
// مختاراً بشكل إفتراضي عند تشغيل التطبيق, أي يوجد عليه علامة صح radioMenuItem1 هنا قمنا بجعل الكائن
radioMenuItem1.setSelected(true);
// أم لا radioMenuItem2 و radioMenuItem1 لتحديد ما إذا كان يمكن النقر على الكائنين autoEnableOrDisableMenuOptions() هنا قمنا باستدعاء الدالة
autoEnableOrDisableMenuOptions();
// هنا قمنا بتشغيل التطبيق
public static void main(String[] args) {
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.RadioMenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleGroup;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Main extends Application {
// لأننا ننوي وضع الصورة بداخله pane هنا قمنا بإنشاء كائن من الكلاس
Pane pane = new Pane();
// يمثل الصورة التي تظهر في النافذة Image هنا قمنا بإنشاء كائن من الكلاس
Image image = new Image(getClass().getResourceAsStream("/images/javafx-icon.png"));
// في النافذة image لعرض الصورة التي يشير لها الكائن ImageView هنا قمنا بإنشاء كائن من الكلاس
ImageView imageView = new ImageView(image);
// يمثل القائمة التي تظهر عن النقر بزر الفأرة الأيمن فوق الصورة ContextMenu هنا قمنا بإنشاء كائن من الكلاس
ContextMenu contextMenu = new ContextMenu();
// هنا قمنا بإنشاء جميع الكائنات التي سنستخدمها كعناصر بداخل القائمة
MenuItem menuItem1 = new MenuItem("Rotate Right");
MenuItem menuItem2 = new MenuItem("Rotate Left");
CheckMenuItem checkMenuItem = new CheckMenuItem("Show Border");
RadioMenuItem radioMenuItem1 = new RadioMenuItem("Black Border");
RadioMenuItem radioMenuItem2 = new RadioMenuItem("Blue Border");
// radioMenuItem2 و radioMenuItem1 لأننا ننوي وضع الكائنين toggleGroup هنا قمنا بإنشاء كائن من الكلاس
// لاحقاً في مجموعة واحدة لجعل المستخدم قادر على إختيار إحداهما في كل مرة و ليس كلاهما
ToggleGroup toggleGroup = new ToggleGroup();
// الذي يحتوي على الصورة pane هنا قمنا بتعريف دالة خاصة لرسم أو إخفاء حدود الكائن
public void drawBorderOnDemande()
{
// checkMenuItem إذا كان يوجد على صح على الكائن
if (checkMenuItem.isSelected())
{
// pane سيتم إظهار حدود لونها أزرق للكائن radioMenuItem1 إذا كان يوجد علامة صح على الكائن
if (radioMenuItem1.isSelected())
{
pane.setStyle("-fx-border-style: solid; -fx-border-color: black;");
}
// pane سيتم إظهار حدود لونها أسود للكائن radioMenuItem2 إذا كان يوجد علامة صح على الكائن
else
{
pane.setStyle("-fx-border-style: solid; -fx-border-color: blue;");
}
}
// pane سيتم إزالة الحدود عن الكائن checkMenuItem إذا لم يكن هناك علامة صح على الكائن
else
{
pane.setStyle("-fx-border:none;");
}
}
// قابلين للنقر أم لا radioMenuItem2 و radioMenuItem1 هنا قمنا بتعريف دالة خاصة لتحديد ما إذا كان يجب جعل الكائنين
public void autoEnableOrDisableMenuOptions()
{
// قابلين للنقر radioMenuItem2 و radioMenuItem1 سيتم جعل الكائنين checkMenuItem إذا قام المستخدم بوضع علامة صح على الكائن
if (checkMenuItem.isSelected())
{
radioMenuItem1.setDisable(false);
radioMenuItem2.setDisable(false);
}
// غير قابلين للنقر radioMenuItem2 و radioMenuItem1 سيتم جعل الكائنين checkMenuItem إذا قام المستخدم بإزالة علامة الصح عن الكائن
else
{
radioMenuItem1.setDisable(true);
radioMenuItem2.setDisable(true);
}
}
@Override
public void start(Stage stage) {
// في النافذة pane هنا قمنا بتحديد حجم و مكان الكائن
pane.setPrefSize(202, 202);
pane.setTranslateX(99);
pane.setTranslateY(24);
// pane في الكائن imageView هنا قمنا بوضع الكائن
pane.getChildren().add(imageView);
// للأننا وضعناه بداخله pane بالنسبة للكائن imageView هنا قمنا بتحديد حجم و مكان الكائن
imageView.setFitWidth(200);
imageView.setFitHeight(200);
imageView.setTranslateX(1);
imageView.setTranslateY(1);
// و هكذا أصبح يمكن إختيار واحد منهم فقط في كل مرة radioMenuItem2 و radioMenuItem1 و ربطنا فيه الكائنين ToggleGroup هنا قمنا بإنشاء كائن من الكلاس
radioMenuItem1.setToggleGroup(toggleGroup);
radioMenuItem2.setToggleGroup(toggleGroup);
// هنا قمنا بوضع كل جميع الكائنات التي أنشأناها خصيصاً لوضعها كعناصر في القائمة بداخلها
contextMenu.getItems().add(menuItem1);
contextMenu.getItems().add(menuItem2);
contextMenu.getItems().add(new SeparatorMenuItem());
contextMenu.getItems().add(checkMenuItem);
contextMenu.getItems().add(new SeparatorMenuItem());
contextMenu.getItems().add(radioMenuItem1);
contextMenu.getItems().add(radioMenuItem2);
// في النافذة Root Node لأننا ننوي جعله الـ Group هنا قمنا بإنشاء كائن من الكلاس
Group root = new Group();
// root في الكائن datePicker هنا قمنا بإضافة الكائن
root.getChildren().add(pane);
// فيها و تحديد حجمها Node كأول root هنا قمنا بإنشاء محتوى النافذة مع تعيين الكائن
Scene scene = new Scene(root, 400, 250);
// هنا وضعنا عنوان للنافذة
stage.setTitle("JavaFX ContextMenu");
// أي وضعنا محتوى النافذة الذي قمنا بإنشائه للنافذة .stage في كائن الـ scene هنا وضعنا كائن الـ
stage.setScene(scene);
// هنا قمنا بإظهار النافذة
stage.show();
// الذي يمثل الصورة imageView هنا قمنا بتحديد ماذا سيحدث عند النقر بواسطة الفأرة على الكائن
imageView.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> {
// في المكان الذي تم النقر عليه (contextMenu) إذا تم النقر على الصورة من الفأرة بواسطة الزر الأيمن, سيتم إظهار القائمة
if (e.getButton() == MouseButton.SECONDARY) {
contextMenu.show(imageView, e.getScreenX(), e.getScreenY());
}
});
// menuItem1 هنا قمنا بتحديد ماذا سيحدث عند النقر على الخيار الذي يمثل الكائن
menuItem1.setOnAction((ActionEvent) -> {
// سيتم جعل الصورة تدور 90 درجة باتجاه اليمين
imageView.setRotate(imageView.getRotate() + 90);
});
// menuItem2 هنا قمنا بتحديد ماذا سيحدث عند النقر على الخيار الذي يمثل الكائن
menuItem2.setOnAction((ActionEvent) -> {
// سيتم جعل الصورة تدور 90 درجة باتجاه اليسار
imageView.setRotate(imageView.getRotate() - 90);
});
// checkMenuItem هنا قمنا بتحديد ماذا سيحدث عند النقر على الخيار الذي يمثل الكائن
checkMenuItem.setOnAction((ActionEvent) -> {
// لتحديد ما إذا كان يجب رسم حدود حول الصورة أم لا autoEnableOrDisableMenuOptions() و drawBorderOnDemande() سيتم إستدعاء الدالتين
// أم لا radioMenuItem2 و radioMenuItem1 و كيف يجب أن يتم تلوين هذه الحدود و لتحديد ما إذا كان يمكن النقر على الكائنين
drawBorderOnDemande();
autoEnableOrDisableMenuOptions();
});
// group تابع للمجموعة RadioButton هنا قمنا بتحديد ماذا سيحدث عند النقر على أي
toggleGroup.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> ov, Toggle toggle, Toggle new_toggle) -> {
drawBorderOnDemande();
});
// غير مختار عند تشغيل التطبيق, أي لا يوجد عليه علامة صح checkMenuItem هنا قمنا بجعل الكائن
checkMenuItem.setSelected(false);
// مختاراً بشكل إفتراضي عند تشغيل التطبيق, أي يوجد عليه علامة صح radioMenuItem1 هنا قمنا بجعل الكائن
radioMenuItem1.setSelected(true);
// أم لا radioMenuItem2 و radioMenuItem1 لتحديد ما إذا كان يمكن النقر على الكائنين autoEnableOrDisableMenuOptions() هنا قمنا باستدعاء الدالة
autoEnableOrDisableMenuOptions();
}
// هنا قمنا بتشغيل التطبيق
public static void main(String[] args) {
launch(args);
}
}