-
-
Save mmdemirbas/07f7cb0840d68ef00e75cd60e9b97ce1 to your computer and use it in GitHub Desktop.
| package com.mmdemirbas.lab; | |
| /** | |
| * Created by md on 5.04.2016. | |
| */ | |
| import javafx.application.Application; | |
| import javafx.application.Platform; | |
| import javafx.collections.FXCollections; | |
| import javafx.collections.ObservableList; | |
| import javafx.embed.swing.JFXPanel; | |
| import javafx.geometry.Bounds; | |
| import javafx.scene.Scene; | |
| import javafx.scene.control.*; | |
| import javafx.scene.input.KeyCode; | |
| import javafx.scene.layout.HBox; | |
| import javafx.scene.layout.VBox; | |
| import javafx.stage.Popup; | |
| import javafx.stage.Stage; | |
| import javafx.stage.Window; | |
| import javafx.util.Callback; | |
| import javafx.util.StringConverter; | |
| import javax.swing.*; | |
| import java.time.LocalDate; | |
| import java.time.format.DateTimeFormatter; | |
| public class MultiDatePicker extends Application { | |
| public static void main(String[] args) { | |
| // launch(args); | |
| launchSwing(); | |
| } | |
| private static void launchSwing() { | |
| SwingUtilities.invokeLater(() -> { | |
| JFrame frame = new JFrame("Swing and JavaFX"); | |
| final JFXPanel fxPanel = new JFXPanel(); | |
| frame.add(fxPanel); | |
| frame.setVisible(true); | |
| frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
| Platform.runLater(() -> fxPanel.setScene(createScene())); | |
| }); | |
| } | |
| private static Scene createScene() { | |
| Button addButton = new Button("+"); | |
| Button removeButton = new Button("-"); | |
| ObservableList<LocalDate> selectedDates = FXCollections.observableArrayList(); | |
| ListView<LocalDate> dateList = new ListView<>(selectedDates); | |
| String pattern = "yyyy-MM-dd"; | |
| DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(pattern); | |
| DatePicker datePicker = new DatePicker(); | |
| datePicker.setShowWeekNumbers(true); | |
| datePicker.setOnAction(event -> System.out.println("Selected date: " + datePicker.getValue())); | |
| datePicker.setPromptText(pattern); | |
| datePicker.setConverter(new StringConverter<LocalDate>() { | |
| @Override | |
| public String toString(LocalDate date) { | |
| return (date == null) ? "" : dateFormatter.format(date); | |
| } | |
| @Override | |
| public LocalDate fromString(String string) { | |
| return ((string == null) || string.isEmpty()) ? null : LocalDate.parse(string, dateFormatter); | |
| } | |
| }); | |
| datePicker.setOnAction(event -> selectedDates.add(datePicker.getValue())); | |
| datePicker.setDayCellFactory(new Callback<DatePicker, DateCell>() { | |
| @Override | |
| public DateCell call(DatePicker param) { | |
| return new DateCell() { | |
| @Override | |
| public void updateItem(LocalDate item, boolean empty) { | |
| super.updateItem(item, empty); | |
| boolean alreadySelected = selectedDates.contains(item); | |
| setDisable(alreadySelected); | |
| setStyle(alreadySelected ? "-fx-background-color: #09a30f;" : ""); | |
| } | |
| }; | |
| } | |
| }); | |
| // TODO: Hide text field of the date picker combo. Show dropdown directly on clicking "+" button. | |
| // TODO: Keep dropdown of the date picker combo open until intentionally clicking some other where. | |
| dateList.setOnKeyPressed(event -> { | |
| if (event.getCode() == KeyCode.DELETE) { | |
| removeSelectedDates(selectedDates, dateList); | |
| } | |
| }); | |
| dateList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); | |
| removeButton.disableProperty().bind(dateList.getSelectionModel().selectedItemProperty().isNull()); | |
| addButton.setOnAction(event -> { | |
| Popup popup = new Popup(); | |
| popup.getContent().add(datePicker); | |
| popup.setAutoHide(true); | |
| Window window = addButton.getScene().getWindow(); | |
| Bounds bounds = addButton.localToScene(addButton.getBoundsInLocal()); | |
| double x = window.getX() + bounds.getMinX(); | |
| double y = window.getY() + bounds.getMinY() + bounds.getHeight() + 5; | |
| popup.show(addButton, x, y); | |
| datePicker.show(); | |
| }); | |
| removeButton.setOnAction(event -> removeSelectedDates(selectedDates, dateList)); | |
| HBox buttons = new HBox(addButton, removeButton); | |
| return new Scene(new VBox(buttons, dateList)); | |
| } | |
| private static boolean removeSelectedDates(ObservableList<LocalDate> selectedDates, ListView<LocalDate> dateList) { | |
| return selectedDates.removeAll(dateList.getSelectionModel().getSelectedItems()); | |
| } | |
| @Override | |
| public void start(Stage primaryStage) { | |
| primaryStage.setScene(createScene()); | |
| primaryStage.show(); | |
| } | |
| } |
mmdemirbas
commented
Apr 5, 2016


This looks ideal for my JavaFX app. I changed the package and the class names. Unfortunately when I tried to use it, I hit a problem with JFXPanel.
Please can you help?
"C:\Program Files\Java\jdk-15.0.2\bin\java.exe" --module-path "C:\Program Files\Java\javafx-sdk-16\lib" --add-modules javafx.controls,javafx.fxml --add-exports javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.3.2\lib\idea_rt.jar=50564:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.3.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Users\Ted\IdeaProjects\PerfectWindows\out\production\Fixtures;C:\Program Files\Java\javafx-sdk-16\lib\src.zip;C:\Program Files\Java\javafx-sdk-16\lib\javafx-swt.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.web.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.base.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.fxml.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.media.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.swing.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.controls.jar;C:\Program Files\Java\javafx-sdk-16\lib\javafx.graphics.jar" fixturesPkg.Main
Exception in thread "AWT-EventQueue-0" java.lang.IllegalAccessError: class javafx.embed.swing.JFXPanel (in unnamed module @0x676e7187) cannot access class com.sun.javafx.logging.PlatformLogger (in module javafx.base) because module javafx.base does not export com.sun.javafx.logging to unnamed module @0x676e7187
at javafx.embed.swing.JFXPanel.(JFXPanel.java:136)
at fixturesPkg.Main.lambda$launchSwing$1(Main.java:38)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
I was using JDK 8 when I wrote this piece of code. I can see from the output that you are using JDK 15. The error seems related to the Java module system which is introduced on JDK 9 as I remember. I'm afraid I don't know much about the module system. But I can say that your problem is unrelated to the MultiDatePicker code itself. I believe you can find some related material when you search for the error on the Internet. For example, I found the following quick results when I searched this phrase:
IllegalAccessError: class javafx.embed.swing.JFXPanel (in unnamed module @0x676e7187) cannot access class com.sun.javafx.logging.PlatformLogger (in module javafx.base) because module javafx.base does not export com.sun.javafx.logging to unnamed module