개발 환경 설정
- JavaFX 개발 환경 설정(넷빈즈 8.2, 오라클 JDK 1.8, Scene Builder)
- Scene Builder에 라이브러리 추가 하는 방법(JFoeniX, FontAwesomeFX)
- 넷빈즈 프로젝트 외부 라이브러리(jar) 등록하는 방법
설명
기존에 시스템(OS)에서 제공하는 형태의 제목표시줄(타이틀바)를 제거하고 직접 디자인하여 제목표시줄의 최소화, 최대화, 종료 기능의 버튼을 구현한 예제입니다. 또한 창을 드래그하여 이동뿐만 아니라, 창 이동(마우스 드래그) 시, 투명화 옵션을 주어 좀더 직관적입니다.
결과
프로젝트 다운로드
프로젝트 구조
소스 코드
Launcher.java
package com.ozxexe.custombar;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Launcher extends Application {
// public static Stage stage = null;
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Login.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.initStyle(StageStyle.UNDECORATED);
// this.stage = stage;
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
LoginController.java
package com.ozxexe.custombar;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class LoginController implements Initializable {
@FXML
private AnchorPane parent;
@FXML
private HBox top;
@FXML
private Pane content;
private double xOffset = 0;
private double yOffset = 0;
private Stage stage = null;
@Override
public void initialize(URL url, ResourceBundle rb) {
stageDragableMoveWindow();
}
private void stageDragableMoveWindow() {
parent.setOnMousePressed((event) -> {
xOffset = event.getSceneX();
yOffset = event.getSceneY();
});
parent.setOnMouseDragged((event) -> {
// Launcher.stage.setX(event.getScreenX() - xOffset);
// Launcher.stage.setY(event.getScreenY() - yOffset);
// Launcher.stage.setOpacity(0.8f); // 창 투명화
stage = (Stage) parent.getScene().getWindow();
stage.setX(event.getScreenX() - xOffset);
stage.setY(event.getScreenY() - yOffset);
stage.setOpacity(0.8f); // 창 투명화
});
parent.setOnDragDone((event) -> {
// Launcher.stage.setOpacity(1.0f);
stage = (Stage) parent.getScene().getWindow();
stage.setOpacity(1.0f);
});
parent.setOnMouseReleased((event) -> {
// Launcher.stage.setOpacity(1.0f);
stage = (Stage) parent.getScene().getWindow();
stage.setOpacity(1.0f);
});
}
@FXML
private void actionMinWindow(MouseEvent event) {
// Launcher.stage.setIconified(true);
stage = (Stage) parent.getScene().getWindow();
stage.setIconified(true);
}
@FXML
private void actionMaxWindow(MouseEvent event) {
// Launcher.stage.setFullScreen(true);
// if (Launcher.stage.isMaximized()) {
// Launcher.stage.setMaximized(false);
// } else {
// Launcher.stage.setMaximized(true);
// }
stage = (Stage) parent.getScene().getWindow();
if (stage.isMaximized()) {
stage.setMaximized(false);
} else {
stage.setMaximized(true);
}
}
@FXML
private void actionCloseWindow(MouseEvent event) {
System.exit(0);
}
@FXML
private void handle_login(ActionEvent event) {
}
}
Login.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXButton?>
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" fx:id="parent" prefHeight="540.0" prefWidth="1024.0" styleClass="parent" stylesheets="@css/style.css" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/11.0.1" fx:controller="com.ozxexe.custombar.LoginController">
<children>
<HBox fx:id="top" alignment="CENTER_RIGHT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="35.0" prefWidth="1024.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<children>
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#actionMinWindow" prefHeight="30.0" prefWidth="30.0" styleClass="min-btn">
<graphic>
<FontAwesomeIconView glyphName="MINUS" glyphStyle="-fx-fill:white" size="13.0" />
</graphic>
</Label>
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#actionMaxWindow" prefHeight="30.0" prefWidth="30.0" styleClass="max-btn">
<graphic>
<FontAwesomeIconView glyphName="SQUARE" glyphStyle="-fx-fill:white" size="13.0" />
</graphic>
</Label>
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#actionCloseWindow" prefHeight="30.0" prefWidth="30.0" styleClass="close-btn">
<graphic>
<FontAwesomeIconView glyphName="CLOSE" glyphStyle="-fx-fill:white" size="13.0" />
</graphic>
</Label>
</children>
</HBox>
<Pane fx:id="content" layoutY="35.0" prefHeight="545.0" prefWidth="1024.0">
<children>
<HBox alignment="CENTER_LEFT" layoutX="387.0" layoutY="188.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0" prefWidth="250.0">
<children>
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0" prefWidth="45.0" style="-fx-background-color: #363b41;">
<graphic>
<FontAwesomeIconView glyphName="USER" glyphStyle="-fx-fill:#ADADAD" size="15.0" />
</graphic>
</Label>
<TextField minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0" prefWidth="45.0" promptText="Username" styleClass="txtfield" HBox.hgrow="ALWAYS">
<font>
<Font size="14.0" />
</font>
</TextField>
</children>
</HBox>
<HBox alignment="CENTER_LEFT" layoutX="387.0" layoutY="248.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0" prefWidth="250.0">
<children>
<Label alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0" prefWidth="45.0" style="-fx-background-color: #363b41;">
<graphic>
<FontAwesomeIconView glyphName="LOCK" glyphStyle="-fx-fill:#ADADAD" size="15.0" />
</graphic>
</Label>
<PasswordField minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0" prefWidth="45.0" promptText="Password" styleClass="txtfield" HBox.hgrow="ALWAYS">
<font>
<Font size="14.0" />
</font>
</PasswordField>
</children>
</HBox>
<JFXButton buttonType="RAISED" layoutX="387.0" layoutY="313.0" minHeight="-Infinity" minWidth="-Infinity" onAction="#handle_login" prefHeight="45.0" prefWidth="250.0" ripplerFill="WHITE" styleClass="login-btn" text="SIGN IN" />
</children>
</Pane>
</children>
</AnchorPane>
참고사이트
'Java | JavaFX' 카테고리의 다른 글
JavaFX 네비게이션 메뉴 클릭할때 마다 컨텐츠(*.fxml) 페이지 불러오기 예제 (0) | 2019.12.28 |
---|---|
JavaFX 페이스북 디자인의 로그인(TimeLine를 활용한 화면 전환 애니메이션) (0) | 2019.12.27 |
JavaFX AnimateFX 데모 예제 (0) | 2019.12.26 |
JavaFX 제목표시줄(타이틀바) 없애는 방법 예제 (0) | 2019.12.26 |
JavaFX 마우스 오버 시, 슬라이드 메뉴 예제 (0) | 2019.12.26 |