Sadece JavaFX'i keşfettim ve gerçekten beğendim. Java varsayılan GUI'den nefret ediyorum, bu yüzden hemen penceremi kişiselleştirmeye karar verdim. Çok sayıda denemem vardı ama büyük bir kısıtlama ve büyük bir hedefim var; sınırlaması? MVC kalıbını kullanmalıyım. Amaç? Özel pencereyi tekrar kullanılabilir hale getirin. Ben App.java içeren genel bir paket uygulaması yapılanJavaFX - basit özel minimum pencere uygulaması
wstaw.org/m/2016/04/07/resoruces.png, Vasiyet:
Yani ... Bu Artık hiç sahip noktasıdır uygulamayı başlat. Sonra ihtiyacım olan tüm resoruces ile, "MinimalWindow" mantığını containin başka bir iç paket yapmak.
package application.minimalWindow;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class MinimalWindow extends Application {
@FXML
Label lblTitle;
@FXML
Button btnMax, btnResize;
@FXML
StackPane minimalWindowShadowContainer, minimalWindowContainer,contentArea;
@FXML
Double SHADOW_SPACE;
final private static int MIN_WIDTH = 730, MIN_HEIGHT = 500;
private double actualX, actualY;
private boolean isMovable;
private String source, title;
private Stage mainStage;
//
// Public logic of the class
//
public MinimalWindow() {
//TODO must work...
}
//Show the window
public void show() {
mainStage.show();
}
//
// MIMIZIE | MAXIMIZE | CLOSE
//
//When pressed, will minimize the window to tray
@FXML
private void minimizeApp(MouseEvent e) {
mainStage.setIconified(true);
}
//When pressed, check if it must maximize or restore the window
@FXML
private void maximizeApp(MouseEvent e) {
if (mainStage.isMaximized()) {
setMin();
isMovable = true;
}
else {
setMax();
isMovable = false;
}
}
//When pressed, will kill the window
@FXML
private void closeApp(MouseEvent e) {
mainStage.close();
System.exit(0);
}
//
// WINDOW MOVING
//
//When i must update the XY of the click
@FXML
private void updateXY(MouseEvent e){
actualX = e.getScreenX() - mainStage.getX();
actualY = e.getScreenY() - mainStage.getY();
}
//When pressing and dragging the mouse it will move the window
@FXML
private void windowDragging(MouseEvent e) {
if (isMovable) {
mainStage.setX(e.getScreenX() - actualX);
mainStage.setY(e.getScreenY() - actualY);
}
else {
//setMin();
mainStage.setX(e.getScreenX());
mainStage.setY(e.getScreenY());
}
}
//Update the status of the window from not movable to movable, after "normalize" effect
//from the dragging it when it's maximized
@FXML
private void updateStatus(MouseEvent e) {
if (mainStage.isMaximized() == false) {
isMovable = true;
}
}
//
// WINDOW RESIZING
//
/*onMouseEntered="#setMouseCursor" onMouseExited="#resetMouseCursor" onMouseDragged="#resizeWindow"*/
@FXML
private void setMouseCursor (MouseEvent e) {
minimalWindowContainer.setCursor(Cursor.CROSSHAIR);
}
@FXML
private void resetMouseCursor (MouseEvent e) {
minimalWindowContainer.setCursor(Cursor.DEFAULT);
}
@FXML
private void resizeWindow (MouseEvent e) {
actualX = e.getScreenX() - mainStage.getX() + 13;
actualY = e.getScreenY() - mainStage.getY() + 10;
if (actualX % 5 == 0 || actualY % 5 == 0) {
if (actualX > MIN_WIDTH) {
mainStage.setWidth(actualX);
} else {
mainStage.setWidth(MIN_WIDTH);
}
if (actualY > MIN_HEIGHT) {
mainStage.setHeight(actualY);
} else {
mainStage.setHeight(MIN_HEIGHT);
}
}
}
//
// Internal methods
//
//Will set the window to MAXIMIZE size
private void setMax() {
mainStage.setMaximized(true);
btnResize.setVisible(false);
btnMax.setStyle("-fx-background-image: url('/res/dSquare.png');");
minimalWindowContainer.setPadding(new Insets(0, 0, 0, 0));
}
//Will set the window to NORMAL size
private void setMin() {
mainStage.setMaximized(false);
btnResize.setVisible(true);
btnMax.setStyle("-fx-background-image: url('/res/square.png');");
minimalWindowContainer.setPadding(new Insets(SHADOW_SPACE, SHADOW_SPACE, SHADOW_SPACE, SHADOW_SPACE));
}
@Override
public void start(Stage primaryStage) {
/* //NOT SURE IF DOING RIGHT YA'
try {
//Prepare the resource with the FXML file
FXMLLoader loader = new FXMLLoader(getClass().getResource("/application/minimalWindow/MainWindow.fxml"));
//Load the main stackpane
Parent root = loader.load();
loader.setController(this);
//Prepare the content of the window, with a minWidth/Height
Scene scene = new Scene(root, MIN_WIDTH, MIN_HEIGHT);
//Making the scene transparent
scene.setFill(Color.TRANSPARENT);
//Undecorate the window due its persolalisation
primaryStage.initStyle(StageStyle.TRANSPARENT);
//Set the content of the window
primaryStage.setScene(scene); *
}
catch (Exception e) {
e.printStackTrace();
} */
}
ve stil için CSS: In
* {
/* Some general colors */
primaryColor: #f9f9f9;
secondaryColor: derive(primaryColor, -75%);
textColor: white;
closeBtnColor: red;
}
#titleBar, #footer {
-fx-background-color: secondaryColor;
}
#title {
-fx-text-fill: textColor;
}
#contentArea {
-fx-background-color: primaryColor;
}
#minimalWindowShadowContainer {
-fx-background-color: transparent;
-fx-effect: dropshadow(gaussian , black , 5,0,0,0);
-fx-background-insets: 5;
}
#btnCls, #btnMax, #btnMin, #btnResize {
-fx-background-color: transparent;
-fx-background-radius: 0;
-fx-border-color: transparent;
-fx-border-width: 0;
-fx-background-position: center;
-fx-background-repeat: stretch;
}
#btnMax:hover, #btnMin:hover {
-fx-background-color: derive(secondaryColor, 20%);
}
#btnCls:hover {
-fx-background-color: derive(red, 45%);
}
#btnCls {
-fx-background-image: url('/res/x.png');
}
#btnMax {
-fx-background-image: url('/res/square.png');
}
#btnMin {
-fx-background-image: url('/res/line.png');
}
#btnResize {
-fx-background-image: url('/res/resize.png');
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.control.Label?>
<StackPane fx:id="minimalWindowShadowContainer" id="minimalWindowShadowContainer" stylesheets="@style.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" onMousePressed="#updateXY" onMouseDragged="#windowDragging" onMouseReleased="#updateStatus" >
<BorderPane fx:id="minimalWindowContainer" id="minimalWindowContainer">
<!-- This padding will create the dropshadow effect for the window behind -->
<padding>
<Insets top="5" right="5" bottom="5" left="5"/>
</padding>
<!-- "Title Bar" -->
<top>
<HBox id="titleBar" alignment="CENTER" spacing="5" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="30.0" prefWidth="600.0">
<padding>
<Insets top="5" right="5" bottom="5" left="5"/>
</padding>
<ImageView fx:id="logo" fitWidth="20" fitHeight="20"></ImageView>
<Label fx:id="lblTitle" id="title" text="MinimalWindow"></Label>
<Region HBox.hgrow="ALWAYS" prefHeight="30.0" prefWidth="200.0"></Region>
<HBox alignment="CENTER_RIGHT">
<Button id="btnMin" onMouseClicked="#minimizeApp" minHeight="20" minWidth="20" maxHeight="20" maxWidth="20"></Button>
<Button fx:id="btnMax" id="btnMax" onMouseClicked="#maximizeApp" minHeight="20" minWidth="20" maxHeight="20" maxWidth="20"></Button>
<Button id="btnCls" onMouseClicked="#closeApp" minHeight="20" minWidth="20" maxHeight="20" maxWidth="20"></Button>
</HBox>
</HBox>
</top>
<!-- The content of the window will go here -->
<center>
<StackPane fx:id="contentArea" id="contentArea"></StackPane>
</center>
<!-- Footer -->
<bottom>
<HBox id="footer">
<padding>
<Insets top="5" right="5" bottom="5" left="5"/>
</padding>
<Button fx:id="btnResize" id="btnResize" alignment="BOTTOM_RIGHT" onMouseClicked="#updateXY" onMouseEntered="#setMouseCursor" onMouseExited="#resetMouseCursor" onMouseDragged="#resizeWindow" minHeight="10" minWidth="10" maxHeight="10" maxWidth="10"></Button>
</HBox>
</bottom>
</BorderPane>
</StackPane>
Sonra denetleyici sınıfını hayata:
pencereyi gerçekleştirmek için bu FXML kodunu uyguladıktan App.java Bunu şu şekilde kullanmalıyım:public class App {
public static void main(String[] args) {
//Initialize the minimal window
MinimalWindow mainWindow = new MinimalWindow();
//Show the window, after all
mainWindow.show();
}
}
Buradaki çözümümüzü internette yayınlamıyorum. MVC modelinde özel stil konusunda tam olarak bir şey bulunamadı (evet ... sınav projesi için yapmam gerekiyor).
Sorunlar nelerdir? Kullanımı ve tekrar kullanımı kolay olmalı. Böyle yapıcı yapmaya çalışıyorum: java.lang:
public MinimalWindow(String title, String source) {
this.title = title;
this.source = source;
start(mainStage);
}
bana 11 satırda XAML dosyası (StackPanel tanımlayan ilk satırı) ayrıştırma, ya da bana Yarattığı bir hata" vererek hataları verir. IllegalStateException: Toolkit başlatılmamış ". İlk olarak, neyin neden olduğunu bilmiyorum. İkincisi, internet üzerindeki çözüm benim dersimi Uygulama'dan genişletmeyi ve “başlangıç” yöntemini geçersiz kılmayı önerdi, ama işe yaramadı.
Soru zaman: herhangi bir çözüm? Öneriler?
Not: Farklı tarzı ile, çalışmak olmayan bir mvc desende bu kod yapmak ve o amele büyük:
wstaw.org/m/2016/04/07/ezgif.com-crop.gif
@James_D sen başarmak istediğini anlamak görünüyor:
Bu
sonucudur. % 100 emin değilim. Özel pencere süslemeleri ile ilgili ise, Undecorator'dan gelen kodu kontrol ederek, bunun nasıl yapılacağına bir göz atabilirsiniz. Belki bu yardımcı olur: [Undecorator @ Github] (https://github.com/in-sideFX/Undecorator) – dzimUndercoator çok sorunlu ve ben bunu kendi başıma yapmayı tercih ediyorum, çünkü uygulamanın aslında ne yaptığını bilmem gerekiyor. Denedim, ne yapabileceğini gördüm, ama gerçekten istediğim gibi çalışan hiçbir şey yapamam. İstediğim sonuç benzer, ancak uygulanması ve kullanılması daha kolay. O zaman kaynağı daha iyi kontrol edeceğim. – Martinocom
Tamam, genel dileğini anlıyorum. Ve evet: Sadece çok çok [x kez tekrar ediyorum] yeni olduğunda Undecorator çalıştı. Sadece ona bir göz atmayı önerdim, bunu nasıl başarabilirsin. Ayrıca, bir e (fx) klip grubu Google grubundaki eski bir gönderiyi (henüz bir resmi Eclipse projesi olmadığında - JavaFX'in 2 katında) iki kez suçluyor ve içerik oluşturucudan bu konuda yardım almasını istemiştim. Bkz. [Burada] (https://groups.google.com/forum/#!topic/efxclipse/bNneRaIBNN0) - Google önbelleğinde bulunan iki GitHub sayfasının bağlantılarına hâlâ erişebilirsiniz. Kara büyü yok. Eksik olan yeniden boyutlandırmadır. – dzim