🏃‍♂️ Hızlı Notlar

JavaFX 12 için hızlı notlar

Proje Dizin Yapısı

JavaFX için önerilen dizin yapısı aşağıdaki gibidir. (kaynak)

  • Çalışmaları gruplandırmak için com/yemreak/myproject yapısı kullanılmakta

    • Maven veya gradle yapısı olarak da geçmektedir

  • controllers, FXML dosyalarını kontrol eden kodlar

  • services, Harici hizmetler (veya tüm hizmetler)

    • Eğer çok fazla hizmet varsa, yerel hizmetleri farklı dizine alabilirsin

  • utility, Dahili hizmetler

  • resources, Tüm kod dışı kaynaklar (images, css, html vs.)

  • views, FXML tasarımları

src/main
├──java/com/yemreak/myproject (ya da sadece myproject)
├── controllers
├──Screen1controller.java
├──Screen2controller.java
├── services
├──Service1.java
├── applications
├── SaveProducts.java
├──resources
├──views
├──screen1.fxml
├──screen2.fxml
├──css
├──style.css
├──images
├──img1.jpg
├──img2.jpg

Örnek olacak proje için buraya bakabilirsin

Dosyaları Yapılandırma

Dizinleri IDE üzerinden yapılandırak daha verimli çalışabilirsin.

  • Project Structure - Project Settings - Modules

  • Source sekmesinden src/res dizinini Resources olarak tanıt

  • out, lib ve res dosyalarını Excluded olarak tanıt

jetbrains_project_structures

Kaynak

Hızlı Notlar

  • İlk önce Controller clasına ekle sonra Scene Builder tarafında fx:id'ye eşle

  • drive.png okunmuyor ama google_drive.png okunuyor

    • Refactor ile ismi yenilenirse de düzeliyor

    • Resimlerin herbiri src dizinininin altında olmalı

  • Üst üste tasarımlar için tasarım yapacağın paneli Hierarchy kısmından en alta alırsan, diğerlerinin üstüne gelir ve karışmaz

  • Ya da visible değerini false yaparsın

  • En alta alınan program çalıştığında ilk görülendir

JPackage ile Çıkarma

  • İlk olarak buradan JPackage'ı indirmen lazım.

MSPaint adlı yazılım JPackage ile çıkarılmış (?)

Kod Notları

Kod Tarafında CSS Değiştirme

buttonDownload.setStyle("-fx-background-image: url('/images/verified.png')");

Thread ile Kodlama

JavaFX'de oluşturulan Thread, FX'in threadına uyumsuz olarak ilerleyebilmekte, bu durumda Not on FX application thread; currentThread = JavaFX Application Thread error? hatası gelemektedir.

  • FX (arayüzden) bağımsız Thread'lerdee sorun oluşmaz.

  • Arayüzü bağımlı Thread'lerde Platform.runAfter{() -> {}} yapısı kullanılır

  • Thread'i platformdan sonra başlat anlamına gelmektedir

new Thread(() -> {
Image resim = uzunSürenBirİşlem();
imageView.setImage(resim); // Bu udurmda thread ile FX yapısı kesişir ve hata verir
}).start();
new Thread(() -> {
Image resim = uzunSürenBirİşlem();
Platform.runAfter(() -> imageView.setImage(resim)); // Yapısı ile FX hazır olduktan sonra işlem yapılır
}).start();

CSS ile Stil Oluşturma

  • Buton gibi alt öğrelere .buton css class'ı ile özellik tanımlayabilirsin

  • Her eleman içinde bulunduğu panelin css özelliğini taşır

FXML'de Kod Yapısı

<TextField prefWidth="50" text="${speedSlider.value}"/> <!-- Inline code -->
<Slider fx:id="speedSlider" orientation="HORIZONTAL" prefWidth="300"
min="60" max="100000" blockIncrement="100"/>

Slider'a göre Label'ı güncelleme

Slider Listener (Kaydırmalı çubuğun değişikliğine göre tepki verme)

Silder objesinden herhangi bir özelliği (...Property) alıp ona uygun listener ekleyebiliriz.

// Listener örneği
sliderQuality.valueProperty().addListener((observableValue, number, t1) -> {
updateFileSize();
});

Slider'a göre Label'ı güncelleme

Çerçeveleri Kaldırma

primaryStage.initStyle(StageStyle.TRANSPARENT);

Arkaplanı Transparant Yapma

  • İlk olarak .fxml dosyasındaki gerekli objeye style="-fx-background-color: transparent ;" özelliği ekleyin

  • Ardından kod tarafında alttaki düzeltmeyi yapın

primaryStage.setScene(new Scene(root));
primaryStage.getScene().setFill(Color.TRANSPARENT);

Clipboard (Pano) İşlemleri

private void putClipboard(String clipboardString) {
StringSelection stringSelection = new StringSelection(clipboardString);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, null);
}
String getClipboard() throws IOException, UnsupportedFlavorException {
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
return (String) clipboard.getData(DataFlavor.stringFlavor);
}

ImageView Resmi Değiştirme

Bu işlem için resource dizini IntelliJ'de işaretlemeniz gerekmektedir.

import javafx.scene.image.Image;
// load an image in background, displaying a placeholder while it's loading
// (assuming there's an ImageView node somewhere displaying this image)
// The image is located in default package of the classpath
Image image1 = new Image("/flower.png", true);
// load an image and resize it to 100x150 without preserving its original
// aspect ratio
// The image is located in my.res package of the classpath
Image image2 = new Image("my/res/flower.png", 100, 150, false, false);
// load an image and resize it to width of 100 while preserving its
// original aspect ratio, using faster filtering method
// The image is downloaded from the supplied URL through http protocol
Image image3 = new Image("http://sample.com/res/flower.png", 100, 0, false, false);
// load an image and resize it only in one dimension, to the height of 100 and
// the original width, without preserving original aspect ratio
// The image is located in the current working directory
Image image4 = new Image("file:flower.png", 0, 100, false, false);

Oracle'ın resmi sitesinden alınmıştır.

Dosya Sürükle Bırak İşlemleri

@FXML
private ImageView imageView;
@FXML
void handleDragOver(DragEvent event) {
if (event.getDragboard().hasFiles()) {
event.acceptTransferModes(TransferMode.ANY);
}
}
@FXML
void handleDragDropped(DragEvent event) throws FileNotFoundException {
List<File> files = event.getDragboard().getFiles();
Image img = new Image(new FileInputStream(files.get(0)));
imageView.setImage(img);
}

Listeners (Eylem Yönetimi)

Ekranı Taşıma İşlemi

public class Main extends Application {
private double xOffset;
private double yOffset;
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root));
primaryStage.show();
root.setOnMousePressed(mouseEvent -> {
xOffset = mouseEvent.getSceneX();
yOffset = mouseEvent.getSceneY();
});
root.setOnMouseDragged(mouseEvent -> {
primaryStage.setX(mouseEvent.getScreenX() - xOffset);
primaryStage.setY(mouseEvent.getScreenY() - yOffset);
});
}
public static void main(String[] args) {
launch(args);
}
}

Harici Bağlantılar