├── liveChatScreenShots ├── liveChatSs1.png └── liveChatSs2.png ├── Client_01 ├── src │ └── main │ │ ├── resources │ │ ├── assests │ │ │ ├── icon │ │ │ │ ├── closeIcon.png │ │ │ │ ├── emojiIcon.png │ │ │ │ ├── backBtnIcon.png │ │ │ │ ├── minimizeIcon.png │ │ │ │ ├── sendBtnIcon.png │ │ │ │ ├── attachmentIcon.png │ │ │ │ ├── emojiIconBlue.png │ │ │ │ ├── lightThemeIcon.png │ │ │ │ ├── nightThemeIcon.png │ │ │ │ ├── backBtnIconSilver.png │ │ │ │ ├── closeIconSilver.png │ │ │ │ ├── sendBtnIconSilver.png │ │ │ │ ├── attachmentIconBlue.png │ │ │ │ ├── minimizeIconSilver.png │ │ │ │ ├── lightThemeIconSilver.png │ │ │ │ └── nightThemeIconSilver.png │ │ │ ├── emoji │ │ │ │ ├── thumbUpEmoji.png │ │ │ │ ├── cryingFaceEmoji.png │ │ │ │ ├── fearfulFaceEmoji.png │ │ │ │ ├── hushedFaceEmoji.png │ │ │ │ ├── smilingFaceEmoji.png │ │ │ │ ├── thumbsDownEmoji.png │ │ │ │ ├── winkingFaceEmoji.png │ │ │ │ ├── grinningFaceEmoji.png │ │ │ │ ├── loudlyCryingEmoji.png │ │ │ │ ├── sleepingFaceEmoji.png │ │ │ │ ├── disappointedFaceEmoji.png │ │ │ │ ├── faceWithTongueEmoji.png │ │ │ │ ├── loveHeartsEyesEmoji.png │ │ │ │ ├── expressionlessFaceEmoji.png │ │ │ │ ├── faceWithTearsOfJoyEmoji.png │ │ │ │ ├── anxiousFaceWithSweatEmoji.png │ │ │ │ ├── smilingFaceWithHaloEmoji.png │ │ │ │ └── smilingFaceWithSunglasses.png │ │ │ └── image │ │ │ │ ├── chatRoomBackground.png │ │ │ │ ├── playTechLogoChatRoom.png │ │ │ │ ├── signInFormBackground.png │ │ │ │ ├── chatRoomBackgroundDark.png │ │ │ │ └── playTechLogoChatRoomDark.png │ │ └── view │ │ │ ├── loginForm.fxml │ │ │ └── chatRoomForm.fxml │ │ └── java │ │ └── lk │ │ └── ijse │ │ └── liveChatRoom │ │ ├── AppInitializer.java │ │ ├── util │ │ ├── TransitionUtil.java │ │ └── NavigationUtil.java │ │ └── controller │ │ ├── LoginFormController.java │ │ └── ChatRoomFormController.java └── pom.xml ├── Client_02 ├── src │ └── main │ │ ├── resources │ │ ├── assests │ │ │ ├── icon │ │ │ │ ├── closeIcon.png │ │ │ │ ├── emojiIcon.png │ │ │ │ ├── backBtnIcon.png │ │ │ │ ├── minimizeIcon.png │ │ │ │ ├── sendBtnIcon.png │ │ │ │ ├── attachmentIcon.png │ │ │ │ ├── emojiIconBlue.png │ │ │ │ ├── lightThemeIcon.png │ │ │ │ ├── nightThemeIcon.png │ │ │ │ ├── backBtnIconSilver.png │ │ │ │ ├── closeIconSilver.png │ │ │ │ ├── sendBtnIconSilver.png │ │ │ │ ├── attachmentIconBlue.png │ │ │ │ ├── minimizeIconSilver.png │ │ │ │ ├── lightThemeIconSilver.png │ │ │ │ └── nightThemeIconSilver.png │ │ │ ├── emoji │ │ │ │ ├── thumbUpEmoji.png │ │ │ │ ├── cryingFaceEmoji.png │ │ │ │ ├── fearfulFaceEmoji.png │ │ │ │ ├── hushedFaceEmoji.png │ │ │ │ ├── smilingFaceEmoji.png │ │ │ │ ├── thumbsDownEmoji.png │ │ │ │ ├── winkingFaceEmoji.png │ │ │ │ ├── grinningFaceEmoji.png │ │ │ │ ├── loudlyCryingEmoji.png │ │ │ │ ├── sleepingFaceEmoji.png │ │ │ │ ├── disappointedFaceEmoji.png │ │ │ │ ├── faceWithTongueEmoji.png │ │ │ │ ├── loveHeartsEyesEmoji.png │ │ │ │ ├── expressionlessFaceEmoji.png │ │ │ │ ├── faceWithTearsOfJoyEmoji.png │ │ │ │ ├── anxiousFaceWithSweatEmoji.png │ │ │ │ ├── smilingFaceWithHaloEmoji.png │ │ │ │ └── smilingFaceWithSunglasses.png │ │ │ └── image │ │ │ │ ├── chatRoomBackground.png │ │ │ │ ├── playTechLogoChatRoom.png │ │ │ │ ├── signInFormBackground.png │ │ │ │ ├── chatRoomBackgroundDark.png │ │ │ │ └── playTechLogoChatRoomDark.png │ │ └── view │ │ │ ├── loginForm.fxml │ │ │ └── chatRoomForm.fxml │ │ └── java │ │ └── lk │ │ └── ijse │ │ └── liveChatRoom │ │ ├── AppInitializer.java │ │ ├── util │ │ ├── TransitionUtil.java │ │ └── NavigationUtil.java │ │ └── controller │ │ ├── LoginFormController.java │ │ └── ChatRoomFormController.java └── pom.xml ├── .idea ├── vcs.xml ├── .gitignore ├── misc.xml ├── encodings.xml └── uiDesigner.xml ├── Server ├── src │ └── main │ │ └── java │ │ └── lk │ │ └── ijse │ │ └── liveChatRoom │ │ ├── ServerInitializer.java │ │ └── server │ │ ├── Server.java │ │ └── ClientHandler.java └── pom.xml ├── .gitignore ├── LICENSE ├── pom.xml └── README.md /liveChatScreenShots/liveChatSs1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/liveChatScreenShots/liveChatSs1.png -------------------------------------------------------------------------------- /liveChatScreenShots/liveChatSs2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/liveChatScreenShots/liveChatSs2.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/closeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/closeIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/emojiIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/emojiIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/closeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/closeIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/emojiIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/emojiIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/backBtnIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/backBtnIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/minimizeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/minimizeIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/sendBtnIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/sendBtnIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/backBtnIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/backBtnIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/minimizeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/minimizeIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/sendBtnIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/sendBtnIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/thumbUpEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/thumbUpEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/attachmentIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/attachmentIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/emojiIconBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/emojiIconBlue.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/lightThemeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/lightThemeIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/nightThemeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/nightThemeIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/thumbUpEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/thumbUpEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/attachmentIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/attachmentIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/emojiIconBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/emojiIconBlue.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/lightThemeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/lightThemeIcon.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/nightThemeIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/nightThemeIcon.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/cryingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/cryingFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/fearfulFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/fearfulFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/hushedFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/hushedFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/smilingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/smilingFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/thumbsDownEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/thumbsDownEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/winkingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/winkingFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/backBtnIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/backBtnIconSilver.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/closeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/closeIconSilver.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/sendBtnIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/sendBtnIconSilver.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/cryingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/cryingFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/fearfulFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/fearfulFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/hushedFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/hushedFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/smilingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/smilingFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/thumbsDownEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/thumbsDownEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/winkingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/winkingFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/backBtnIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/backBtnIconSilver.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/closeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/closeIconSilver.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/sendBtnIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/sendBtnIconSilver.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/grinningFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/grinningFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/loudlyCryingEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/loudlyCryingEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/sleepingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/sleepingFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/attachmentIconBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/attachmentIconBlue.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/minimizeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/minimizeIconSilver.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/image/chatRoomBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/image/chatRoomBackground.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/grinningFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/grinningFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/loudlyCryingEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/loudlyCryingEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/sleepingFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/sleepingFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/attachmentIconBlue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/attachmentIconBlue.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/minimizeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/minimizeIconSilver.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/image/chatRoomBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/image/chatRoomBackground.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/disappointedFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/disappointedFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/faceWithTongueEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/faceWithTongueEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/loveHeartsEyesEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/loveHeartsEyesEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/lightThemeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/lightThemeIconSilver.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/icon/nightThemeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/icon/nightThemeIconSilver.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/image/playTechLogoChatRoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/image/playTechLogoChatRoom.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/image/signInFormBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/image/signInFormBackground.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/disappointedFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/disappointedFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/faceWithTongueEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/faceWithTongueEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/loveHeartsEyesEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/loveHeartsEyesEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/lightThemeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/lightThemeIconSilver.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/icon/nightThemeIconSilver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/icon/nightThemeIconSilver.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/image/playTechLogoChatRoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/image/playTechLogoChatRoom.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/image/signInFormBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/image/signInFormBackground.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/expressionlessFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/expressionlessFaceEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/faceWithTearsOfJoyEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/faceWithTearsOfJoyEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/image/chatRoomBackgroundDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/image/chatRoomBackgroundDark.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/expressionlessFaceEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/expressionlessFaceEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/faceWithTearsOfJoyEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/faceWithTearsOfJoyEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/image/chatRoomBackgroundDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/image/chatRoomBackgroundDark.png -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/anxiousFaceWithSweatEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/anxiousFaceWithSweatEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/smilingFaceWithHaloEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/smilingFaceWithHaloEmoji.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/emoji/smilingFaceWithSunglasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/emoji/smilingFaceWithSunglasses.png -------------------------------------------------------------------------------- /Client_01/src/main/resources/assests/image/playTechLogoChatRoomDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_01/src/main/resources/assests/image/playTechLogoChatRoomDark.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/anxiousFaceWithSweatEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/anxiousFaceWithSweatEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/smilingFaceWithHaloEmoji.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/smilingFaceWithHaloEmoji.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/emoji/smilingFaceWithSunglasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/emoji/smilingFaceWithSunglasses.png -------------------------------------------------------------------------------- /Client_02/src/main/resources/assests/image/playTechLogoChatRoomDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gayanukabulegoda/Live-Chat-Room/HEAD/Client_02/src/main/resources/assests/image/playTechLogoChatRoomDark.png -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /Server/src/main/java/lk/ijse/liveChatRoom/ServerInitializer.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom; 2 | 3 | import lk.ijse.liveChatRoom.server.Server; 4 | 5 | public class ServerInitializer { 6 | public static void main(String[] args) { 7 | Server server = new Server(); 8 | server.initialize(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | !**/src/main/**/build/ 32 | !**/src/test/**/build/ 33 | 34 | ### VS Code ### 35 | .vscode/ 36 | 37 | ### Mac OS ### 38 | .DS_Store -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | lk.ijse 8 | liveChatRoom 9 | 1.0-SNAPSHOT 10 | 11 | 12 | Server 13 | 14 | 15 | 11 16 | 11 17 | UTF-8 18 | 19 | 20 | -------------------------------------------------------------------------------- /Client_01/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | lk.ijse 8 | liveChatRoom 9 | 1.0-SNAPSHOT 10 | 11 | 12 | Client_01 13 | 14 | 15 | 11 16 | 11 17 | UTF-8 18 | 19 | 20 | -------------------------------------------------------------------------------- /Client_02/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | lk.ijse 8 | liveChatRoom 9 | 1.0-SNAPSHOT 10 | 11 | 12 | Client_02 13 | 14 | 15 | 11 16 | 11 17 | UTF-8 18 | 19 | 20 | -------------------------------------------------------------------------------- /Client_01/src/main/java/lk/ijse/liveChatRoom/AppInitializer.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Scene; 6 | import javafx.stage.Stage; 7 | import javafx.stage.StageStyle; 8 | 9 | public class AppInitializer extends Application { 10 | public static Stage loginStage; 11 | 12 | public static void main(String[] args) { 13 | launch(args); 14 | } 15 | 16 | @Override 17 | public void start(Stage stage) throws Exception { 18 | stage.setScene( 19 | new Scene( 20 | FXMLLoader.load(getClass().getResource("/view/loginForm.fxml")))); 21 | 22 | stage.initStyle(StageStyle.UNDECORATED); 23 | stage.centerOnScreen(); 24 | stage.show(); 25 | loginStage = stage; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Client_02/src/main/java/lk/ijse/liveChatRoom/AppInitializer.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom; 2 | 3 | import javafx.application.Application; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Scene; 6 | import javafx.stage.Stage; 7 | import javafx.stage.StageStyle; 8 | 9 | public class AppInitializer extends Application { 10 | 11 | public static Stage loginStage; 12 | 13 | public static void main(String[] args) { 14 | launch(args); 15 | } 16 | 17 | @Override 18 | public void start(Stage stage) throws Exception { 19 | stage.setScene( 20 | new Scene( 21 | FXMLLoader.load(getClass().getResource("/view/loginForm.fxml")))); 22 | 23 | stage.initStyle(StageStyle.DECORATED); 24 | stage.centerOnScreen(); 25 | stage.show(); 26 | loginStage = stage; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Client_01/src/main/java/lk/ijse/liveChatRoom/util/TransitionUtil.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.util; 2 | 3 | import javafx.animation.ScaleTransition; 4 | import javafx.scene.Node; 5 | import javafx.scene.image.ImageView; 6 | import javafx.scene.layout.Pane; 7 | import javafx.util.Duration; 8 | 9 | public class TransitionUtil { 10 | 11 | public static void ScaleTransition(Object... arg) { 12 | Node node = (Node) arg[0]; 13 | if (node instanceof Pane) { 14 | ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(0.2), node); 15 | scaleTransition.setFromX(0); 16 | scaleTransition.setToX(1); 17 | scaleTransition.setFromY(0); 18 | scaleTransition.setToY(1); 19 | scaleTransition.play(); 20 | } 21 | else if (node instanceof ImageView) { 22 | double scale = (double) arg[1]; 23 | node.setScaleX(scale); 24 | node.setScaleY(scale); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Client_02/src/main/java/lk/ijse/liveChatRoom/util/TransitionUtil.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.util; 2 | 3 | import javafx.animation.ScaleTransition; 4 | import javafx.scene.Node; 5 | import javafx.scene.image.ImageView; 6 | import javafx.scene.layout.Pane; 7 | import javafx.util.Duration; 8 | 9 | public class TransitionUtil { 10 | 11 | public static void ScaleTransition(Object... arg) { 12 | Node node = (Node) arg[0]; 13 | if (node instanceof Pane) { 14 | ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(0.2), node); 15 | scaleTransition.setFromX(0); 16 | scaleTransition.setToX(1); 17 | scaleTransition.setFromY(0); 18 | scaleTransition.setToY(1); 19 | scaleTransition.play(); 20 | } 21 | else if (node instanceof ImageView) { 22 | double scale = (double) arg[1]; 23 | node.setScaleX(scale); 24 | node.setScaleY(scale); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/src/main/java/lk/ijse/liveChatRoom/server/Server.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.server; 2 | 3 | import java.io.IOException; 4 | import java.net.ServerSocket; 5 | import java.net.Socket; 6 | import java.util.ArrayList; 7 | 8 | public class Server { 9 | 10 | private final ArrayList clients = new ArrayList<>(); 11 | 12 | public void initialize() { 13 | try { 14 | ServerSocket serverSocket = new ServerSocket(3400); 15 | System.out.println("Server Initialized!!!"); 16 | 17 | while (true) { 18 | Socket localSocket = serverSocket.accept(); 19 | System.out.println("New Client Connected!!!"); 20 | 21 | ClientHandler clientThread = new ClientHandler(localSocket,clients); 22 | clients.add(clientThread); 23 | clientThread.start(); 24 | } 25 | } catch (IOException e) { 26 | throw new RuntimeException(e); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Gayanuka Bulegoda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Client_01/src/main/java/lk/ijse/liveChatRoom/util/NavigationUtil.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.util; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Node; 6 | import javafx.scene.Parent; 7 | import javafx.scene.Scene; 8 | import javafx.stage.Stage; 9 | import lk.ijse.liveChatRoom.AppInitializer; 10 | 11 | import java.io.IOException; 12 | 13 | public class NavigationUtil { 14 | 15 | private static Stage stage; 16 | 17 | public static void switchNavigation(String link, ActionEvent event) throws IOException { 18 | Parent parent = FXMLLoader.load(NavigationUtil.class.getResource("/view/" + link)); 19 | stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); 20 | Scene scene = new Scene(parent); 21 | stage.setScene(scene); 22 | stage.centerOnScreen(); 23 | stage.show(); 24 | } 25 | 26 | public static void exit() { 27 | System.exit(0); 28 | } 29 | 30 | public static void minimize() { 31 | if (stage != null) { 32 | stage.setIconified(true); 33 | } 34 | else if (AppInitializer.loginStage != null) { 35 | AppInitializer.loginStage.setIconified(true); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Client_02/src/main/java/lk/ijse/liveChatRoom/util/NavigationUtil.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.util; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.FXMLLoader; 5 | import javafx.scene.Node; 6 | import javafx.scene.Parent; 7 | import javafx.scene.Scene; 8 | import javafx.stage.Stage; 9 | import lk.ijse.liveChatRoom.AppInitializer; 10 | 11 | import java.io.IOException; 12 | 13 | public class NavigationUtil { 14 | 15 | private static Stage stage; 16 | 17 | public static void switchNavigation(String link, ActionEvent event) throws IOException { 18 | Parent parent = FXMLLoader.load(NavigationUtil.class.getResource("/view/" + link)); 19 | stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); 20 | Scene scene = new Scene(parent); 21 | stage.setScene(scene); 22 | stage.centerOnScreen(); 23 | stage.show(); 24 | } 25 | 26 | public static void exit() { 27 | System.exit(0); 28 | } 29 | 30 | public static void minimize() { 31 | if (stage != null) { 32 | stage.setIconified(true); 33 | } 34 | else if (AppInitializer.loginStage != null) { 35 | AppInitializer.loginStage.setIconified(true); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | lk.ijse 8 | liveChatRoom 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | Server 13 | Client_01 14 | Client_02 15 | 16 | 17 | 18 | 11 19 | 11 20 | UTF-8 21 | 22 | 23 | 24 | org.openjfx 25 | javafx-controls 26 | 19.0.2.1 27 | 28 | 29 | org.openjfx 30 | javafx-fxml 31 | 19.0.2.1 32 | 33 | 34 | com.jfoenix 35 | jfoenix 36 | 9.0.10 37 | 38 | 39 | -------------------------------------------------------------------------------- /Server/src/main/java/lk/ijse/liveChatRoom/server/ClientHandler.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.server; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.net.Socket; 8 | import java.util.ArrayList; 9 | 10 | public class ClientHandler extends Thread { 11 | 12 | private final Socket localSocket; 13 | private final ArrayList clients; 14 | private final BufferedReader bufferedReader; 15 | private final PrintWriter printWriter; 16 | 17 | public ClientHandler(Socket localSocket, ArrayList clients) { 18 | try { 19 | this.localSocket = localSocket; 20 | this.clients = clients; 21 | this.bufferedReader = new BufferedReader(new InputStreamReader(localSocket.getInputStream())); 22 | this.printWriter = new PrintWriter(localSocket.getOutputStream(),true); 23 | } catch (IOException e) { 24 | throw new RuntimeException(e); 25 | } 26 | } 27 | 28 | @Override 29 | public void run() { 30 | try { 31 | String message; 32 | while ((message = bufferedReader.readLine()) != null) { 33 | for (ClientHandler client : clients) { 34 | client.printWriter.println(message); 35 | } 36 | } 37 | } 38 | catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | finally { 42 | try { 43 | printWriter.close(); 44 | bufferedReader.close(); 45 | localSocket.close(); 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Client_01/src/main/java/lk/ijse/liveChatRoom/controller/LoginFormController.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.controller; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.TextField; 7 | import javafx.scene.input.KeyCode; 8 | import javafx.scene.input.KeyEvent; 9 | import javafx.scene.input.MouseEvent; 10 | import javafx.scene.layout.Pane; 11 | import lk.ijse.liveChatRoom.util.NavigationUtil; 12 | import lk.ijse.liveChatRoom.util.TransitionUtil; 13 | 14 | import java.io.IOException; 15 | import java.util.regex.Pattern; 16 | 17 | public class LoginFormController { 18 | 19 | @FXML 20 | private TextField txtUserName; 21 | 22 | @FXML 23 | private Label lblUserNameAlert; 24 | 25 | @FXML 26 | private Pane signInBtnPane; 27 | 28 | @FXML 29 | private Pane exitBtnPane; 30 | 31 | @FXML 32 | private Pane minimizeBtnPane; 33 | 34 | public static String username; 35 | 36 | @FXML 37 | void signInBtnOnAction(ActionEvent event) throws IOException { 38 | if (validateUsername()) { 39 | username = txtUserName.getText(); 40 | NavigationUtil.switchNavigation("chatRoomForm.fxml", event); 41 | } 42 | else { 43 | lblUserNameAlert.setText("Invalid! Username should have at least\n" + 44 | "FOUR characters (except Symbols & Spaces)"); 45 | } 46 | } 47 | 48 | @FXML 49 | void signInBtnOnMouseEntered(MouseEvent event) { 50 | signInBtnPane.setStyle( 51 | "-fx-background-color: #018DE7;" + 52 | "-fx-background-radius: 15px"); 53 | } 54 | 55 | @FXML 56 | void signInBtnOnMouseExited(MouseEvent event) { 57 | signInBtnPane.setStyle( 58 | "-fx-background-color: #009CFF;" + 59 | "-fx-background-radius: 15px"); 60 | } 61 | 62 | @FXML 63 | void txtUserNameOnAction(ActionEvent event) throws IOException { 64 | signInBtnOnAction(event); 65 | } 66 | 67 | @FXML 68 | void btnMinimizeOnAction(ActionEvent event) { 69 | NavigationUtil.minimize(); 70 | } 71 | 72 | @FXML 73 | void btnExitOnAction(ActionEvent event) { 74 | NavigationUtil.exit(); 75 | } 76 | 77 | @FXML 78 | void btnExitOnMouseEntered(MouseEvent event) { 79 | exitBtnPane.setVisible(true); 80 | TransitionUtil.ScaleTransition(exitBtnPane); 81 | } 82 | 83 | @FXML 84 | void btnExitOnMouseExited(MouseEvent event) { 85 | exitBtnPane.setVisible(false); 86 | } 87 | 88 | @FXML 89 | void btnMinimizeOnMouseEntered(MouseEvent event) { 90 | minimizeBtnPane.setVisible(true); 91 | TransitionUtil.ScaleTransition(minimizeBtnPane); 92 | } 93 | 94 | @FXML 95 | void btnMinimizeOnMouseExited(MouseEvent event) { 96 | minimizeBtnPane.setVisible(false); 97 | } 98 | 99 | @FXML 100 | void txtUserNameOnKeyPressed(KeyEvent event) { 101 | if ((event.getCode() == KeyCode.BACK_SPACE) || (event.getCode() == KeyCode.DELETE)) { 102 | lblUserNameAlert.setText(" "); 103 | } 104 | } 105 | 106 | private boolean validateUsername() { 107 | return Pattern.matches("^[a-zA-Z0-9]{4,}$", txtUserName.getText()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Client_02/src/main/java/lk/ijse/liveChatRoom/controller/LoginFormController.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.controller; 2 | 3 | import javafx.event.ActionEvent; 4 | import javafx.fxml.FXML; 5 | import javafx.scene.control.Label; 6 | import javafx.scene.control.TextField; 7 | import javafx.scene.input.KeyCode; 8 | import javafx.scene.input.KeyEvent; 9 | import javafx.scene.input.MouseEvent; 10 | import javafx.scene.layout.Pane; 11 | import lk.ijse.liveChatRoom.util.NavigationUtil; 12 | import lk.ijse.liveChatRoom.util.TransitionUtil; 13 | 14 | import java.io.IOException; 15 | import java.util.regex.Pattern; 16 | 17 | public class LoginFormController { 18 | 19 | @FXML 20 | private TextField txtUserName; 21 | 22 | @FXML 23 | private Label lblUserNameAlert; 24 | 25 | @FXML 26 | private Pane signInBtnPane; 27 | 28 | @FXML 29 | private Pane exitBtnPane; 30 | 31 | @FXML 32 | private Pane minimizeBtnPane; 33 | 34 | public static String username; 35 | 36 | @FXML 37 | void signInBtnOnAction(ActionEvent event) throws IOException { 38 | if (validateUsername()) { 39 | username = txtUserName.getText(); 40 | NavigationUtil.switchNavigation("chatRoomForm.fxml", event); 41 | } 42 | else { 43 | lblUserNameAlert.setText("Invalid! Username should have at least\n" + 44 | "FOUR characters (except Symbols & Spaces)"); 45 | } 46 | } 47 | 48 | @FXML 49 | void signInBtnOnMouseEntered(MouseEvent event) { 50 | signInBtnPane.setStyle( 51 | "-fx-background-color: #018DE7;" + 52 | "-fx-background-radius: 15px"); 53 | } 54 | 55 | @FXML 56 | void signInBtnOnMouseExited(MouseEvent event) { 57 | signInBtnPane.setStyle( 58 | "-fx-background-color: #009CFF;" + 59 | "-fx-background-radius: 15px"); 60 | } 61 | 62 | @FXML 63 | void txtUserNameOnAction(ActionEvent event) throws IOException { 64 | signInBtnOnAction(event); 65 | } 66 | 67 | @FXML 68 | void btnMinimizeOnAction(ActionEvent event) { 69 | NavigationUtil.minimize(); 70 | } 71 | 72 | @FXML 73 | void btnExitOnAction(ActionEvent event) { 74 | NavigationUtil.exit(); 75 | } 76 | 77 | @FXML 78 | void btnExitOnMouseEntered(MouseEvent event) { 79 | exitBtnPane.setVisible(true); 80 | TransitionUtil.ScaleTransition(exitBtnPane); 81 | } 82 | 83 | @FXML 84 | void btnExitOnMouseExited(MouseEvent event) { 85 | exitBtnPane.setVisible(false); 86 | } 87 | 88 | @FXML 89 | void btnMinimizeOnMouseEntered(MouseEvent event) { 90 | minimizeBtnPane.setVisible(true); 91 | TransitionUtil.ScaleTransition(minimizeBtnPane); 92 | } 93 | 94 | @FXML 95 | void btnMinimizeOnMouseExited(MouseEvent event) { 96 | minimizeBtnPane.setVisible(false); 97 | } 98 | 99 | @FXML 100 | void txtUserNameOnKeyPressed(KeyEvent event) { 101 | if ((event.getCode() == KeyCode.BACK_SPACE) || (event.getCode() == KeyCode.DELETE)) { 102 | lblUserNameAlert.setText(" "); 103 | } 104 | } 105 | 106 | private boolean validateUsername() { 107 | return Pattern.matches("^[a-zA-Z0-9]{4,}$", txtUserName.getText()); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | # drawing PlayTech Live Chat 4 | 5 |
6 | 7 | Welcome to Play Tech's Chat! This networked chat application, developed for Play Tech Pvt Ltd.'s customer service division, is meticulously crafted with socket programming. 8 | 9 | ## Overview 10 | 11 | Designed to elevate employee experience and reduce stress during work, this app seamlessly connects support team members. It transforms customer interactions into a dynamic and stress-free experience, empowering the Play Tech support team with a user-friendly platform. 12 | 13 | Embrace a more engaging and supportive work environment with the PlayTech Chat application, developed with cutting-edge socket programming techniques. 14 | 15 | ## Table of Contents 16 | 17 | - [Visual Insights](#visual-insights) 18 | - [Features](#features) 19 | - [Getting Started](#getting-started) 20 | - [Prerequisites](#prerequisites) 21 | - [Installation](#installation) 22 | - [Usage](#usage) 23 | - [License](#license) 24 | 25 | ## Visual Insights 26 | 27 |
28 | 29 |

30 | 31 |

32 | 33 | ## Features 34 | 35 | - Seamless User Authentication: Log in effortlessly to the chat room using a personalized username. 36 | - Versatile Messaging: Share messages, emojis, and even photos with other users, fostering dynamic communication. 37 | - Flexible User Interaction: Join, leave, or minimize the chat at your convenience, providing flexibility in participation. 38 | - Personalized Theme Preferences: Tailor your chat experience with the option to switch between the visually appealing dark and light modes. 39 | 40 | ## Getting Started 41 | 42 | ### Prerequisites 43 | 44 | Before you begin, ensure you have met the following requirements: 45 | 46 | - Java Development Kit 11 (JDK) installed. 47 | - Integrated Development Environment (IDE) like IntelliJ IDEA or Eclipse. 48 | 49 | ### Installation 50 | 51 | 1. Clone the repository: 52 | 53 | ```bash 54 | https://github.com/gayanukabulegoda/Live-Chat-Room.git 55 | ``` 56 | 57 | 2. Open the project in your IDE. 58 | 3. Build and run the application. 59 | 60 | ## Usage 61 | 62 | To run the project, follow these steps: 63 | 64 | 1. Open the project in your IDE. 65 | 2. Build and run the application. 66 | 67 | For any additional inquiries or information, please do not hesitate to contact me at grbulegoda@gmail.com 68 | 69 | ## License 70 | 71 | This project is licensed under [MIT License](LICENSE). 72 | 73 | ## 74 |
75 | 76 | 77 | 78 | 79 | 80 | 81 |

82 |

83 | © 2024 Gayanuka Bulegoda 84 |

85 | -------------------------------------------------------------------------------- /Client_01/src/main/resources/view/loginForm.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /Client_02/src/main/resources/view/loginForm.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Client_01/src/main/resources/view/chatRoomForm.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | -------------------------------------------------------------------------------- /Client_02/src/main/resources/view/chatRoomForm.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | -------------------------------------------------------------------------------- /Client_01/src/main/java/lk/ijse/liveChatRoom/controller/ChatRoomFormController.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.controller; 2 | 3 | import com.jfoenix.controls.JFXButton; 4 | import javafx.application.Platform; 5 | import javafx.event.ActionEvent; 6 | import javafx.fxml.FXML; 7 | import javafx.geometry.Insets; 8 | import javafx.geometry.Pos; 9 | import javafx.scene.Node; 10 | import javafx.scene.control.Label; 11 | import javafx.scene.control.ScrollPane; 12 | import javafx.scene.control.TextField; 13 | import javafx.scene.image.Image; 14 | import javafx.scene.image.ImageView; 15 | import javafx.scene.layout.HBox; 16 | import javafx.scene.layout.Pane; 17 | import javafx.scene.layout.VBox; 18 | import javafx.scene.paint.Color; 19 | import javafx.scene.text.Font; 20 | import javafx.scene.text.Text; 21 | import javafx.scene.text.TextFlow; 22 | import javafx.scene.shape.Circle; 23 | import javafx.scene.input.MouseEvent; 24 | import javafx.scene.input.KeyEvent; 25 | import javafx.stage.FileChooser; 26 | import lk.ijse.liveChatRoom.util.NavigationUtil; 27 | import lk.ijse.liveChatRoom.util.TransitionUtil; 28 | 29 | import java.io.*; 30 | import java.net.Socket; 31 | import java.nio.file.Files; 32 | import java.time.LocalDateTime; 33 | import java.time.format.DateTimeFormatter; 34 | import java.util.Base64; 35 | import java.util.Random; 36 | import java.util.regex.Pattern; 37 | 38 | public class ChatRoomFormController { 39 | 40 | @FXML 41 | private Circle circleCloseIconInner; 42 | 43 | @FXML 44 | private Circle circleCloseIconOuter; 45 | 46 | @FXML 47 | private Circle circleMinimizeIconInner; 48 | 49 | @FXML 50 | private Circle circleMinimizeIconOuter; 51 | 52 | @FXML 53 | private Circle circleOnlineIndicator; 54 | 55 | @FXML 56 | private Circle circleDarkTheme; 57 | 58 | @FXML 59 | private Circle circleLightTheme; 60 | 61 | @FXML 62 | private ImageView imgBackIcon; 63 | 64 | @FXML 65 | private ImageView imgCloseIcon; 66 | 67 | @FXML 68 | private ImageView imgMinimizeIcon; 69 | 70 | @FXML 71 | private ImageView imgDarkTheme; 72 | 73 | @FXML 74 | private ImageView imgLightTheme; 75 | 76 | @FXML 77 | private ImageView imgPlayTechLogo; 78 | 79 | @FXML 80 | private ImageView imgChatRoomBackground; 81 | 82 | @FXML 83 | private ImageView imgSendBtn; 84 | 85 | @FXML 86 | private ImageView imgAttachIcon; 87 | 88 | @FXML 89 | private ImageView imgEmojiIcon; 90 | 91 | @FXML 92 | private ImageView imgAnxiousFaceWithSweatEmoji; 93 | 94 | @FXML 95 | private ImageView imgCryingFaceEmoji; 96 | 97 | @FXML 98 | private ImageView imgDisappointedFaceEmoji; 99 | 100 | @FXML 101 | private ImageView imgExpressionlessFaceEmoji; 102 | 103 | @FXML 104 | private ImageView imgFaceWithTearsOfJoyEmoji; 105 | 106 | @FXML 107 | private ImageView imgFaceWithTongueEmoji; 108 | 109 | @FXML 110 | private ImageView imgFearfulFaceEmoji; 111 | 112 | @FXML 113 | private ImageView imgGrinningFaceEmoji; 114 | 115 | @FXML 116 | private ImageView imgHushedFaceEmoji; 117 | 118 | @FXML 119 | private ImageView imgLoudlyCryingEmoji; 120 | 121 | @FXML 122 | private ImageView imgLoveHeartsEyesEmoji; 123 | 124 | @FXML 125 | private ImageView imgSleepingFaceEmoji; 126 | 127 | @FXML 128 | private ImageView imgSmilingFaceEmoji; 129 | 130 | @FXML 131 | private ImageView imgSmilingFaceWithHaloEmoji; 132 | 133 | @FXML 134 | private ImageView imgSmilingFaceWithSunglassesEmoji; 135 | 136 | @FXML 137 | private ImageView imgThumbUpEmoji; 138 | 139 | @FXML 140 | private ImageView imgThumbsDownEmoji; 141 | 142 | @FXML 143 | private ImageView imgWinkingFaceEmoji; 144 | 145 | @FXML 146 | private JFXButton backBtn; 147 | 148 | @FXML 149 | private Pane themeChangePane; 150 | 151 | @FXML 152 | private Pane txtMessagePane; 153 | 154 | @FXML 155 | private Pane messageAreaPane; 156 | 157 | @FXML 158 | private Pane sendBtnInnerPane; 159 | 160 | @FXML 161 | private Pane sendBtnOuterPane; 162 | 163 | @FXML 164 | private Pane emojiPane; 165 | 166 | @FXML 167 | private Pane exitBtnPane; 168 | 169 | @FXML 170 | private Pane backBtnPane; 171 | 172 | @FXML 173 | private Pane minimizeBtnPane; 174 | 175 | @FXML 176 | private Label lblUsername; 177 | 178 | @FXML 179 | private Label lblMessageTextAlert; 180 | 181 | @FXML 182 | private ScrollPane scrollPane; 183 | 184 | @FXML 185 | private TextField txtMessage; 186 | 187 | @FXML 188 | private Text txtBack; 189 | 190 | @FXML 191 | private Text txtClose; 192 | 193 | @FXML 194 | private Text txtMinimize; 195 | 196 | @FXML 197 | private Text txtLogoChatRoom; 198 | 199 | @FXML 200 | private VBox vBox; 201 | 202 | private Socket remoteSocket; 203 | private File file; 204 | private String base64Image; 205 | private PrintWriter printWriter; 206 | private BufferedReader bufferedReader; 207 | private String finalName; 208 | 209 | public void initialize() { 210 | lblUsername.setText(LoginFormController.username); 211 | new Thread(()->{ 212 | try { 213 | remoteSocket = new Socket("localhost", 3400); 214 | System.out.println("Client: "+lblUsername.getText()+" Connected!"); 215 | 216 | bufferedReader = new BufferedReader(new InputStreamReader(remoteSocket.getInputStream())); 217 | printWriter = new PrintWriter(remoteSocket.getOutputStream(),true); //like dataOutputStream 218 | 219 | printWriter.println("joi"+lblUsername.getText()+": joining..."); 220 | 221 | while (true) { 222 | //reading the response 223 | String receivedFullMsg = bufferedReader.readLine(); 224 | String[] splitTheMsg = receivedFullMsg.split(":"); 225 | String username = splitTheMsg[0]; 226 | String message = splitTheMsg[1]; 227 | 228 | //finding the arrived message type 229 | String firstCharacter = findingTheArrivedMessageType(username); 230 | 231 | //remove the username prefixes (if available) 232 | removePrefixes(username, firstCharacter); 233 | 234 | //if an Image arrived 235 | if (firstCharacter.equalsIgnoreCase("img")) { 236 | setImage(receivedFullMsg); 237 | } 238 | 239 | // display new client who join the chat 240 | else if (firstCharacter.equalsIgnoreCase("joi")){ 241 | HBox hBox = new HBox(); 242 | if (lblUsername.getText().equals(finalName)) { 243 | Label joinText = new Label("You have joined the Chat"); 244 | 245 | hBox.getChildren().add(joinText); 246 | hBox.setAlignment(Pos.CENTER); 247 | hBox.setPadding(new Insets(5,5,5,10)); 248 | } 249 | else { 250 | Label joinText = new Label(finalName+" has joined the Chat"); 251 | hBox.getChildren().add(joinText); 252 | hBox.setAlignment(Pos.CENTER); 253 | hBox.setPadding(new Insets(5,5,5,10)); 254 | } 255 | 256 | Platform.runLater(() -> 257 | vBox.getChildren().addAll(hBox)); 258 | } 259 | // display the client who left the chat 260 | else if (firstCharacter.equalsIgnoreCase("lef")) { 261 | Label leftText = new Label(finalName + " has left the Chat"); 262 | 263 | HBox hBox = new HBox(); 264 | hBox.getChildren().add(leftText); 265 | hBox.setAlignment(Pos.CENTER); 266 | hBox.setPadding(new Insets(5, 5, 5, 10)); 267 | 268 | Platform.runLater(() -> 269 | vBox.getChildren().add(hBox)); 270 | } 271 | else { 272 | if (lblUsername.getText().equalsIgnoreCase(username)) { 273 | sendMessage(message); 274 | } else { 275 | receivedMessage(receivedFullMsg); 276 | } 277 | } 278 | } 279 | } catch (IOException e) { 280 | e.printStackTrace(); 281 | } 282 | }).start(); 283 | } 284 | 285 | private HBox setTime() { 286 | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm"); 287 | LocalDateTime now = LocalDateTime.now(); 288 | 289 | Text time = new Text(dateTimeFormatter.format(now)); 290 | time.setFont(Font.font(10)); 291 | 292 | HBox timeBox = new HBox(); 293 | timeBox.getChildren().add(time); 294 | timeBox.setAlignment(Pos.BOTTOM_RIGHT); 295 | 296 | return timeBox; 297 | } 298 | 299 | private void removePrefixes(String username, String firstCharacter) { 300 | if (firstCharacter.equalsIgnoreCase("img")) { 301 | String[] name = username.split("img"); //to remove prefix "img" 302 | finalName = name[1]; 303 | } 304 | else if (firstCharacter.equalsIgnoreCase("joi")) { 305 | String[] name = username.split("joi"); //to remove prefix "joi" 306 | finalName = name[1]; 307 | } 308 | else if (firstCharacter.equalsIgnoreCase("lef")) { 309 | String[] name = username.split("lef"); //to remove prefix "lef" 310 | finalName = name[1]; 311 | } 312 | } 313 | 314 | private String findingTheArrivedMessageType(String username) { 315 | String firstCharacter = ""; 316 | if (username.length() > 3) { 317 | firstCharacter = username.substring(0, 3); 318 | System.out.println("First Char: " + firstCharacter); 319 | } 320 | return firstCharacter; 321 | } 322 | 323 | private File decodeReceivedImage(String path) throws IOException { 324 | byte[] imageBytes = Base64.getDecoder().decode(path); // Decode Base64 image data 325 | 326 | // Set file path & create a file to save the received image 327 | int randomNumber = new Random().nextInt(1000000); 328 | String fileName = "ReceivedImage_" + randomNumber + ".png"; 329 | File directoryPath = new File("Client_01/src/main/resources/receivedImages"); 330 | File receivedImageFile = new File(directoryPath, fileName); 331 | 332 | // Write the image bytes to the file 333 | try (FileOutputStream fos = new FileOutputStream(receivedImageFile)) { 334 | fos.write(imageBytes); 335 | } 336 | return receivedImageFile; 337 | } 338 | 339 | private void setImage(String receivedFullMsg) throws IOException { 340 | String[] splitMessage = receivedFullMsg.split(":"); 341 | String path = splitMessage[1]; 342 | System.out.println("Message Path :" + path); 343 | 344 | File receivedImageFile = decodeReceivedImage(path); 345 | 346 | Image receivedImage = new Image(receivedImageFile.toURI().toString()); 347 | 348 | ImageView imageView = new ImageView(receivedImage); 349 | imageView.setFitHeight(300); 350 | imageView.setFitWidth(300); 351 | imageView.setPreserveRatio(true); 352 | 353 | HBox imageBox = new HBox(imageView); 354 | imageBox.setPadding(new Insets(5)); 355 | 356 | HBox hBox = new HBox(10); 357 | hBox.setAlignment(Pos.BOTTOM_RIGHT); 358 | 359 | // Created an inner HBox to contain both the imageHBox and timeHBox 360 | HBox innerHBox = new HBox(); 361 | innerHBox.setPadding(new Insets(5,10,5,10)); 362 | 363 | // Add time 364 | HBox timeBox = setTime(); 365 | 366 | //if received Image selected by me 367 | if (lblUsername.getText().equalsIgnoreCase(finalName)) { 368 | // Set color for the Text within the timeBox 369 | for (Node node : timeBox.getChildren()) { 370 | if (node instanceof Text) { 371 | ((Text) node).setFill(Color.color(0.934, 0.945, 0.996)); 372 | } 373 | } 374 | 375 | if (circleLightTheme.isVisible()) { 376 | innerHBox.setStyle( 377 | "-fx-background-color: rgb(15,125,242);" + 378 | "-fx-background-radius: 20px" 379 | ); 380 | } else { 381 | innerHBox.setStyle( 382 | "-fx-background-color: rgb(8, 78, 153);" + 383 | "-fx-background-radius: 20px" 384 | ); 385 | } 386 | 387 | innerHBox.getChildren().addAll(imageBox,timeBox); 388 | 389 | hBox.getChildren().add(innerHBox); 390 | hBox.setAlignment(Pos.TOP_RIGHT); 391 | hBox.setPadding(new Insets(5,5,5,10)); //set space between images 392 | } 393 | 394 | //if received Image selected by another client 395 | else { 396 | if (circleLightTheme.isVisible()) { 397 | innerHBox.setStyle( 398 | "-fx-background-color: rgb(233,233,235);" + 399 | "-fx-background-radius: 20px" 400 | ); 401 | } else { 402 | innerHBox.setStyle( 403 | "-fx-background-color: #A9A9A9;" + 404 | "-fx-background-radius: 20px" 405 | ); 406 | } 407 | 408 | vBox.setAlignment(Pos.TOP_LEFT); 409 | hBox.setAlignment(Pos.TOP_LEFT); 410 | 411 | Text text = new Text(" " + finalName + " :"); 412 | text.setFont(Font.font(12.5)); 413 | 414 | innerHBox.getChildren().addAll(text,imageBox,timeBox); 415 | hBox.getChildren().add(innerHBox); 416 | hBox.setPadding(new Insets(5,5,5,10)); 417 | } 418 | 419 | Platform.runLater(() -> { 420 | vBox.getChildren().add(hBox); 421 | scrollPane.layout(); // Ensure layout is updated 422 | scrollPane.setVvalue(1.0); // Scroll down to the bottom 423 | }); 424 | } 425 | 426 | private void sendMessage(String messageToSend) { 427 | if (!messageToSend.isEmpty()) { 428 | HBox hBox = new HBox(); 429 | hBox.setAlignment(Pos.CENTER_RIGHT); 430 | hBox.setPadding(new Insets(5,10,5,10)); 431 | 432 | // Created an inner HBox to contain both the message and time 433 | HBox innerHBox = new HBox(); 434 | innerHBox.setPadding(new Insets(2,10,2.5,10)); 435 | 436 | Text text = new Text(messageToSend); 437 | text.setFont(Font.font(17)); 438 | TextFlow textFlow = new TextFlow(text); 439 | 440 | if (circleLightTheme.isVisible()) { 441 | innerHBox.setStyle( 442 | "-fx-background-color: rgb(15,125,242);" + 443 | "-fx-background-radius: 20px" 444 | ); 445 | } else { 446 | innerHBox.setStyle( 447 | "-fx-background-color: rgb(8, 78, 153);" + 448 | "-fx-background-radius: 20px" 449 | ); 450 | } 451 | 452 | textFlow.setPadding(new Insets(5,10,5,10)); 453 | text.setFill(Color.color(0.934, 0.945, 0.996)); 454 | 455 | // Add time 456 | HBox timeBox = setTime(); 457 | 458 | // Set color for the Text within the timeBox 459 | for (Node node : timeBox.getChildren()) { 460 | if (node instanceof Text) { 461 | ((Text) node).setFill(Color.color(0.934, 0.945, 0.996)); 462 | } 463 | } 464 | 465 | innerHBox.getChildren().addAll(textFlow, timeBox); 466 | hBox.getChildren().add(innerHBox); 467 | 468 | Platform.runLater(new Runnable() { 469 | @Override 470 | public void run() { 471 | vBox.getChildren().add(hBox); 472 | scrollPane.layout(); // Ensure layout is updated 473 | scrollPane.setVvalue(1.0); // Scroll down to the bottom 474 | } 475 | }); 476 | } 477 | } 478 | 479 | private void receivedMessage(String receivedMsg) { 480 | String[] name = receivedMsg.split(":"); 481 | String username = name[0]; 482 | String message = name[1]; 483 | 484 | if (!lblUsername.getText().equals(username)) { 485 | HBox hBox = new HBox(); 486 | hBox.setAlignment(Pos.CENTER_LEFT); 487 | hBox.setPadding(new Insets(5,5,5,10)); 488 | 489 | // Created an inner HBox to contain both the message and time 490 | HBox innerHBox = new HBox(); 491 | innerHBox.setPadding(new Insets(2,10,2.5,5)); 492 | 493 | Text txtUsername = new Text(username + ": "); 494 | txtUsername.setFont(Font.font(12.5)); 495 | 496 | Text txtMessage = new Text(message); 497 | txtMessage.setFont(Font.font(17)); 498 | 499 | TextFlow textFlow = new TextFlow(txtUsername, txtMessage); 500 | 501 | if (circleLightTheme.isVisible()) { 502 | innerHBox.setStyle( 503 | "-fx-background-color: rgb(233,233,235);" + 504 | "-fx-background-radius: 20px" 505 | ); 506 | } else { 507 | innerHBox.setStyle( 508 | "-fx-background-color: #A9A9A9;" + 509 | "-fx-background-radius: 20px" 510 | ); 511 | } 512 | 513 | textFlow.setPadding(new Insets(5,10,5,10)); 514 | 515 | // Add time 516 | HBox timeBox = setTime(); 517 | 518 | innerHBox.getChildren().addAll(textFlow, timeBox); 519 | hBox.getChildren().add(innerHBox); 520 | 521 | Platform.runLater(() -> { 522 | vBox.getChildren().add(hBox); 523 | scrollPane.layout(); 524 | scrollPane.setVvalue(1.0); 525 | }); 526 | } 527 | } 528 | 529 | @FXML 530 | void btnAttachOnAction(ActionEvent event) throws IOException { 531 | lblMessageTextAlert.setText(" "); 532 | FileChooser fileChooser = new FileChooser(); 533 | fileChooser.setTitle("Select an Image!!"); 534 | 535 | FileChooser.ExtensionFilter imageFilter = 536 | new FileChooser.ExtensionFilter("Image Files","*.jpg","*.jpeg","*.png","*.gif"); 537 | 538 | fileChooser.getExtensionFilters().add(imageFilter); 539 | file = fileChooser.showOpenDialog(txtMessage.getScene().getWindow()); 540 | 541 | if (file != null) { 542 | txtMessage.setText("01 Image Selected"); 543 | txtMessage.setEditable(false); 544 | 545 | // Read image file into byte array 546 | byte[] imageBytes = Files.readAllBytes(file.toPath()); 547 | base64Image = Base64.getEncoder().encodeToString(imageBytes); 548 | 549 | btnSendOnAction(event); 550 | imgAttachIcon.setImage(new Image("assests/icon/attachmentIcon.png")); 551 | } 552 | } 553 | 554 | @FXML 555 | void btnAttachOnMouseEntered(MouseEvent event) { 556 | imgAttachIcon.setImage(new Image("assests/icon/attachmentIconBlue.png")); 557 | } 558 | 559 | @FXML 560 | void btnAttachOnMouseExited(MouseEvent event) { 561 | imgAttachIcon.setImage(new Image("assests/icon/attachmentIcon.png")); 562 | } 563 | 564 | @FXML 565 | void btnEmojiOnAction(ActionEvent event) { 566 | lblMessageTextAlert.setText(" "); 567 | emojiPane.setVisible(!emojiPane.isVisible()); 568 | if (emojiPane.isVisible()) { 569 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIconBlue.png")); 570 | } else { 571 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 572 | } 573 | } 574 | 575 | @FXML 576 | void btnEmojiOnMouseEntered(MouseEvent event) { 577 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIconBlue.png")); 578 | } 579 | 580 | @FXML 581 | void btnEmojiOnMouseExited(MouseEvent event) { 582 | if (!emojiPane.isVisible()) { 583 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 584 | } 585 | } 586 | 587 | @FXML 588 | void btnBackOnAction(ActionEvent event) throws IOException { 589 | printWriter.println("lef" + lblUsername.getText() + ": leaving"); 590 | NavigationUtil.switchNavigation("loginForm.fxml",event); 591 | } 592 | 593 | @FXML 594 | void btnExitOnAction(ActionEvent event) { 595 | printWriter.println("lef" + lblUsername.getText() + ": leaving"); 596 | NavigationUtil.exit(); 597 | } 598 | 599 | @FXML 600 | void btnMinimizeOnAction(ActionEvent event) { 601 | NavigationUtil.minimize(); 602 | } 603 | 604 | @FXML 605 | void btnExitOnMouseEntered(MouseEvent event) { 606 | exitBtnPane.setVisible(true); 607 | TransitionUtil.ScaleTransition(exitBtnPane); 608 | } 609 | 610 | @FXML 611 | void btnExitOnMouseExited(MouseEvent event) { 612 | exitBtnPane.setVisible(false); 613 | } 614 | 615 | @FXML 616 | void btnMinimizeOnMouseEntered(MouseEvent event) { 617 | minimizeBtnPane.setVisible(true); 618 | TransitionUtil.ScaleTransition(minimizeBtnPane); 619 | } 620 | 621 | @FXML 622 | void btnMinimizeOnMouseExited(MouseEvent event) { 623 | minimizeBtnPane.setVisible(false); 624 | } 625 | 626 | @FXML 627 | void btnBackOnMouseEntered(MouseEvent event) { 628 | backBtnPane.setVisible(true); 629 | TransitionUtil.ScaleTransition(backBtnPane); 630 | if (circleLightTheme.isVisible()) { 631 | backBtn.setStyle( 632 | "-fx-border-color: white;" + 633 | "-fx-border-width: 3px;" + 634 | "-fx-border-radius: 50px"); 635 | } else { 636 | backBtn.setStyle( 637 | "-fx-border-color: #CBCBCB;" + 638 | "-fx-border-width: 3px;" + 639 | "-fx-border-radius: 50px"); 640 | } 641 | } 642 | 643 | @FXML 644 | void btnBackOnMouseExited(MouseEvent event) { 645 | backBtn.setStyle("-fx-border-color: transparent"); 646 | backBtnPane.setVisible(false); 647 | } 648 | 649 | @FXML 650 | void btnSendOnAction(ActionEvent event) { 651 | if (validateMessage()){ 652 | if (file != null) { 653 | printWriter.println("img"+lblUsername.getText() +":"+ base64Image); 654 | file = null; 655 | } else { 656 | printWriter.println(lblUsername.getText() + ": " + txtMessage.getText()); 657 | } 658 | txtMessage.setEditable(true); 659 | emojiPane.setVisible(false); 660 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 661 | txtMessage.clear(); 662 | } 663 | else { 664 | lblMessageTextAlert.setText("Message should have at least a character!!"); 665 | } 666 | } 667 | 668 | private boolean validateMessage() { 669 | return Pattern.matches("^.+$", txtMessage.getText()); 670 | } 671 | 672 | @FXML 673 | void btnSendOnMouseEntered(MouseEvent event) { 674 | TransitionUtil.ScaleTransition(imgSendBtn, 1.1); 675 | if (circleLightTheme.isVisible()) { 676 | sendBtnInnerPane.setStyle( 677 | "-fx-background-color: #018DE7;" + 678 | "-fx-background-radius: 25px"); 679 | } else { 680 | sendBtnInnerPane.setStyle( 681 | "-fx-background-color: #001727;" + 682 | "-fx-background-radius: 25px"); 683 | } 684 | } 685 | 686 | @FXML 687 | void btnSendOnMouseExited(MouseEvent event) { 688 | TransitionUtil.ScaleTransition(imgSendBtn, 1.0); 689 | if (circleLightTheme.isVisible()) { 690 | sendBtnInnerPane.setStyle( 691 | "-fx-background-color: #009CFF;" + 692 | "-fx-background-radius: 25px"); 693 | } else { 694 | sendBtnInnerPane.setStyle( 695 | "-fx-background-color: #001F3F;" + 696 | "-fx-background-radius: 25px"); 697 | } 698 | } 699 | 700 | @FXML 701 | void txtMessageOnAction(ActionEvent event) { 702 | btnSendOnAction(event); 703 | } 704 | 705 | @FXML 706 | void txtMessageOnKeyPressed(KeyEvent event) { 707 | if (!txtMessage.getText().isEmpty()) { 708 | lblMessageTextAlert.setText(" "); 709 | } 710 | } 711 | 712 | @FXML 713 | void imgAnxiousFaceWithSweatEmojiOnMouseClicked(MouseEvent event) { 714 | txtMessage.appendText("\uD83D\uDE30"); //😰 715 | finalizeEmojiSelection(event); 716 | } 717 | 718 | @FXML 719 | void imgCryingFaceEmojiOnMouseClicked(MouseEvent event) { 720 | txtMessage.appendText("\uD83D\uDE22"); //😢 721 | finalizeEmojiSelection(event); 722 | } 723 | 724 | @FXML 725 | void imgDisappointedFaceEmojiOnMouseClicked(MouseEvent event) { 726 | txtMessage.appendText("\uD83D\uDE1E"); //😞 727 | finalizeEmojiSelection(event); 728 | } 729 | 730 | @FXML 731 | void imgFaceWithTearsOfJoyEmojiOnMouseClicked(MouseEvent event) { 732 | txtMessage.appendText("\uD83D\uDE02"); //😂 733 | finalizeEmojiSelection(event); 734 | } 735 | 736 | @FXML 737 | void imgFaceWithTongueEmojiOnMouseClicked(MouseEvent event) { 738 | txtMessage.appendText("\uD83D\uDE1B"); //😛 739 | finalizeEmojiSelection(event); 740 | } 741 | 742 | @FXML 743 | void imgFearfulFaceEmojiOnMouseClicked(MouseEvent event) { 744 | txtMessage.appendText("\uD83D\uDE28"); //😦 745 | finalizeEmojiSelection(event); 746 | } 747 | 748 | @FXML 749 | void imgGrinningFaceEmojiOnMouseClicked(MouseEvent event) { 750 | txtMessage.appendText("\uD83D\uDE00"); //😀 751 | finalizeEmojiSelection(event); 752 | } 753 | 754 | @FXML 755 | void imgHushedFaceEmojiOnMouseClicked(MouseEvent event) { 756 | txtMessage.appendText("\uD83D\uDE2F"); //😯 757 | finalizeEmojiSelection(event); 758 | } 759 | 760 | @FXML 761 | void imgLoudlyCryingEmojiOnMouseClicked(MouseEvent event) { 762 | txtMessage.appendText("\uD83D\uDE2D"); //😭 763 | finalizeEmojiSelection(event); 764 | } 765 | 766 | @FXML 767 | void imgLoveHeartsEyesEmojiOnMouseClicked(MouseEvent event) { 768 | txtMessage.appendText("\uD83D\uDE0D"); //😍 769 | finalizeEmojiSelection(event); 770 | } 771 | 772 | @FXML 773 | void imgExpressionlessFaceEmojiOnMouseClicked(MouseEvent event) { 774 | txtMessage.appendText("\uD83D\uDE11"); //😑 775 | finalizeEmojiSelection(event); 776 | } 777 | 778 | @FXML 779 | void imgSleepingFaceEmojiOnMouseClicked(MouseEvent event) { 780 | txtMessage.appendText("\uD83D\uDE34"); //😴 781 | finalizeEmojiSelection(event); 782 | } 783 | 784 | @FXML 785 | void imgSmilingFaceWithSunglassesEmojiOnMouseClicked(MouseEvent event) { 786 | txtMessage.appendText("\uD83D\uDE0E"); //😎 787 | finalizeEmojiSelection(event); 788 | } 789 | 790 | @FXML 791 | void imgSmilingFaceEmojiOnMouseClicked(MouseEvent event) { 792 | txtMessage.appendText("\uD83D\uDE0A"); //😊 793 | finalizeEmojiSelection(event); 794 | } 795 | 796 | @FXML 797 | void imgSmilingFaceWithHaloEmojiOnMouseClicked(MouseEvent event) { 798 | txtMessage.appendText("\uD83D\uDE07"); //😇 799 | finalizeEmojiSelection(event); 800 | } 801 | 802 | @FXML 803 | void imgThumbsDownEmojiOnMouseClicked(MouseEvent event) { 804 | txtMessage.appendText("\uD83D\uDC4E"); //👎 805 | finalizeEmojiSelection(event); 806 | } 807 | 808 | @FXML 809 | void imgThumbUpEmojiOnMouseClicked(MouseEvent event) { 810 | txtMessage.appendText("\uD83D\uDC4D"); //👍 811 | finalizeEmojiSelection(event); 812 | } 813 | 814 | @FXML 815 | void imgWinkingFaceEmojiOnMouseClicked(MouseEvent event) { 816 | txtMessage.appendText("\uD83D\uDE09"); //😉 817 | finalizeEmojiSelection(event); 818 | } 819 | 820 | private void finalizeEmojiSelection(MouseEvent event) { 821 | emojiPane.setVisible(false); 822 | btnEmojiOnMouseExited(event); 823 | txtMessage.requestFocus(); 824 | } 825 | 826 | @FXML 827 | void imgAnxiousFaceWithSweatEmojiOnMouseEntered(MouseEvent event) { 828 | TransitionUtil.ScaleTransition(imgAnxiousFaceWithSweatEmoji, 1.2); 829 | } 830 | 831 | @FXML 832 | void imgAnxiousFaceWithSweatEmojiOnMouseExited(MouseEvent event) { 833 | TransitionUtil.ScaleTransition(imgAnxiousFaceWithSweatEmoji, 1.0); 834 | } 835 | 836 | @FXML 837 | void imgCryingFaceEmojiOnMouseEntered(MouseEvent event) { 838 | TransitionUtil.ScaleTransition(imgCryingFaceEmoji, 1.2); 839 | } 840 | 841 | @FXML 842 | void imgCryingFaceEmojiOnMouseExited(MouseEvent event) { 843 | TransitionUtil.ScaleTransition(imgCryingFaceEmoji, 1.0); 844 | } 845 | 846 | @FXML 847 | void imgDisappointedFaceEmojiOnMouseEntered(MouseEvent event) { 848 | TransitionUtil.ScaleTransition(imgDisappointedFaceEmoji, 1.2); 849 | } 850 | 851 | @FXML 852 | void imgDisappointedFaceEmojiOnMouseExited(MouseEvent event) { 853 | TransitionUtil.ScaleTransition(imgDisappointedFaceEmoji, 1.0); 854 | } 855 | 856 | @FXML 857 | void imgExpressionlessFaceEmojiOnMouseEntered(MouseEvent event) { 858 | TransitionUtil.ScaleTransition(imgExpressionlessFaceEmoji, 1.2); 859 | } 860 | 861 | @FXML 862 | void imgExpressionlessFaceEmojiOnMouseExited(MouseEvent event) { 863 | TransitionUtil.ScaleTransition(imgExpressionlessFaceEmoji, 1.0); 864 | } 865 | 866 | @FXML 867 | void imgFaceWithTearsOfJoyEmojiOnMouseEntered(MouseEvent event) { 868 | TransitionUtil.ScaleTransition(imgFaceWithTearsOfJoyEmoji, 1.2); 869 | } 870 | 871 | @FXML 872 | void imgFaceWithTearsOfJoyEmojiOnMouseExited(MouseEvent event) { 873 | TransitionUtil.ScaleTransition(imgFaceWithTearsOfJoyEmoji, 1.0); 874 | } 875 | 876 | @FXML 877 | void imgFaceWithTongueEmojiOnMouseEntered(MouseEvent event) { 878 | TransitionUtil.ScaleTransition(imgFaceWithTongueEmoji, 1.2); 879 | } 880 | 881 | @FXML 882 | void imgFaceWithTongueEmojiOnMouseExited(MouseEvent event) { 883 | TransitionUtil.ScaleTransition(imgFaceWithTongueEmoji, 1.0); 884 | } 885 | 886 | @FXML 887 | void imgFearfulFaceEmojiOnMouseEntered(MouseEvent event) { 888 | TransitionUtil.ScaleTransition(imgFearfulFaceEmoji, 1.2); 889 | } 890 | 891 | @FXML 892 | void imgFearfulFaceEmojiOnMouseExited(MouseEvent event) { 893 | TransitionUtil.ScaleTransition(imgFearfulFaceEmoji, 1.0); 894 | } 895 | 896 | @FXML 897 | void imgGrinningFaceEmojiOnMouseEntered(MouseEvent event) { 898 | TransitionUtil.ScaleTransition(imgGrinningFaceEmoji, 1.2); 899 | } 900 | 901 | @FXML 902 | void imgGrinningFaceEmojiOnMouseExited(MouseEvent event) { 903 | TransitionUtil.ScaleTransition(imgGrinningFaceEmoji, 1.0); 904 | } 905 | 906 | @FXML 907 | void imgHushedFaceEmojiOnMouseEntered(MouseEvent event) { 908 | TransitionUtil.ScaleTransition(imgHushedFaceEmoji, 1.2); 909 | } 910 | 911 | @FXML 912 | void imgHushedFaceEmojiOnMouseExited(MouseEvent event) { 913 | TransitionUtil.ScaleTransition(imgHushedFaceEmoji, 1.0); 914 | } 915 | 916 | @FXML 917 | void imgLoudlyCryingEmojiOnMouseEntered(MouseEvent event) { 918 | TransitionUtil.ScaleTransition(imgLoudlyCryingEmoji, 1.2); 919 | } 920 | 921 | @FXML 922 | void imgLoudlyCryingEmojiOnMouseExited(MouseEvent event) { 923 | TransitionUtil.ScaleTransition(imgLoudlyCryingEmoji, 1.0); 924 | } 925 | 926 | @FXML 927 | void imgLoveHeartsEyesEmojiOnMouseEntered(MouseEvent event) { 928 | TransitionUtil.ScaleTransition(imgLoveHeartsEyesEmoji, 1.2); 929 | } 930 | 931 | @FXML 932 | void imgLoveHeartsEyesEmojiOnMouseExited(MouseEvent event) { 933 | TransitionUtil.ScaleTransition(imgLoveHeartsEyesEmoji, 1.0); 934 | } 935 | 936 | @FXML 937 | void imgSleepingFaceEmojiOnMouseEntered(MouseEvent event) { 938 | TransitionUtil.ScaleTransition(imgSleepingFaceEmoji, 1.2); 939 | } 940 | 941 | @FXML 942 | void imgSleepingFaceEmojiOnMouseExited(MouseEvent event) { 943 | TransitionUtil.ScaleTransition(imgSleepingFaceEmoji, 1.0); 944 | } 945 | 946 | @FXML 947 | void imgSmilingFaceEmojiOnMouseEntered(MouseEvent event) { 948 | TransitionUtil.ScaleTransition(imgSmilingFaceEmoji, 1.2); 949 | } 950 | 951 | @FXML 952 | void imgSmilingFaceEmojiOnMouseExited(MouseEvent event) { 953 | TransitionUtil.ScaleTransition(imgSmilingFaceEmoji, 1.0); 954 | } 955 | 956 | @FXML 957 | void imgSmilingFaceWithHaloEmojiOnMouseEntered(MouseEvent event) { 958 | TransitionUtil.ScaleTransition(imgSmilingFaceWithHaloEmoji, 1.2); 959 | } 960 | 961 | @FXML 962 | void imgSmilingFaceWithHaloEmojiOnMouseExited(MouseEvent event) { 963 | TransitionUtil.ScaleTransition(imgSmilingFaceWithHaloEmoji, 1.0); 964 | } 965 | 966 | @FXML 967 | void imgSmilingFaceWithSunglassesEmojiOnMouseEntered(MouseEvent event) { 968 | TransitionUtil.ScaleTransition(imgSmilingFaceWithSunglassesEmoji, 1.2); 969 | } 970 | 971 | @FXML 972 | void imgSmilingFaceWithSunglassesEmojiOnMouseExited(MouseEvent event) { 973 | TransitionUtil.ScaleTransition(imgSmilingFaceWithSunglassesEmoji, 1.0); 974 | } 975 | 976 | @FXML 977 | void imgThumbUpEmojiOnMouseEntered(MouseEvent event) { 978 | TransitionUtil.ScaleTransition(imgThumbUpEmoji, 1.2); 979 | } 980 | 981 | @FXML 982 | void imgThumbUpEmojiOnMouseExited(MouseEvent event) { 983 | TransitionUtil.ScaleTransition(imgThumbUpEmoji, 1.0); 984 | } 985 | 986 | @FXML 987 | void imgThumbsDownEmojiOnMouseEntered(MouseEvent event) { 988 | TransitionUtil.ScaleTransition(imgThumbsDownEmoji, 1.2); 989 | } 990 | 991 | @FXML 992 | void imgThumbsDownEmojiOnMouseExited(MouseEvent event) { 993 | TransitionUtil.ScaleTransition(imgThumbsDownEmoji, 1.0); 994 | } 995 | 996 | @FXML 997 | void imgWinkingFaceEmojiOnMouseEntered(MouseEvent event) { 998 | TransitionUtil.ScaleTransition(imgWinkingFaceEmoji, 1.2); 999 | } 1000 | 1001 | @FXML 1002 | void imgWinkingFaceEmojiOnMouseExited(MouseEvent event) { 1003 | TransitionUtil.ScaleTransition(imgWinkingFaceEmoji, 1.0); 1004 | } 1005 | 1006 | private void setLightTheme() { 1007 | imgChatRoomBackground.setImage(new Image("assests/image/chatRoomBackground.png")); 1008 | imgPlayTechLogo.setImage(new Image("assests/image/playTechLogoChatRoom.png")); 1009 | imgDarkTheme.setImage(new Image("assests/icon/nightThemeIcon.png")); 1010 | imgLightTheme.setImage(new Image("assests/icon/lightThemeIcon.png")); 1011 | imgSendBtn.setImage(new Image("assests/icon/sendBtnIcon.png")); 1012 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 1013 | imgCloseIcon.setImage(new Image("assests/icon/closeIcon.png")); 1014 | imgMinimizeIcon.setImage(new Image("assests/icon/minimizeIcon.png")); 1015 | imgBackIcon.setImage(new Image("assests/icon/backBtnIcon.png")); 1016 | 1017 | // Apply styles directly to vertical scroll bar 1018 | scrollPane.lookup(".scroll-bar:vertical .thumb"). 1019 | setStyle("-fx-background-color: #C0C0C0; -fx-background-radius: 5em;"); 1020 | scrollPane.lookup(".scroll-bar:vertical .track"). 1021 | setStyle("-fx-background-color: transparent; -fx-border-color: transparent;"); 1022 | scrollPane.lookup(".increment-button"). 1023 | setStyle("-fx-background-color: transparent; -fx-border-color: transparent;"); 1024 | scrollPane.lookup(".decrement-button"). 1025 | setStyle("-fx-background-color: transparent; -fx-border-color: transparent;"); 1026 | 1027 | themeChangePane.setStyle("-fx-background-color: white;" + 1028 | "-fx-background-radius: 25px"); 1029 | 1030 | txtLogoChatRoom.setStyle("-fx-fill: white"); 1031 | lblUsername.setStyle("-fx-text-fill: white"); 1032 | circleOnlineIndicator.setStyle("-fx-fill: #009CFF;" + 1033 | "-fx-stroke: white;" + 1034 | "-fx-stroke-width: 3px"); 1035 | 1036 | vBox.setStyle("-fx-background-color: white"); 1037 | scrollPane.setStyle("-fx-background-color: white"); 1038 | messageAreaPane.setStyle("-fx-background-color: white;" + 1039 | "-fx-background-radius: 16px"); 1040 | 1041 | txtMessage.setStyle("-fx-background-color: white"); 1042 | txtMessagePane.setStyle("-fx-background-color: white;" + 1043 | "-fx-background-radius: 25px"); 1044 | 1045 | sendBtnInnerPane.setStyle("-fx-background-color: #009CFF;" + 1046 | "-fx-background-radius: 25px"); 1047 | sendBtnOuterPane.setStyle("-fx-background-color: white;" + 1048 | "-fx-background-radius: 25px"); 1049 | 1050 | emojiPane.setStyle("-fx-background-color: white;" + 1051 | "-fx-border-color: #009CFF;" + 1052 | "-fx-background-radius: 18px;" + 1053 | "-fx-border-radius: 18px"); 1054 | 1055 | circleCloseIconOuter.setStyle("-fx-fill: white"); 1056 | circleCloseIconInner.setStyle("-fx-fill: #009CFF;" + 1057 | "-fx-stroke: #009CFF"); 1058 | 1059 | circleMinimizeIconOuter.setStyle("-fx-fill: white"); 1060 | circleMinimizeIconInner.setStyle("-fx-fill: #009CFF;" + 1061 | "-fx-stroke: #009CFF"); 1062 | 1063 | backBtnPane.setStyle("-fx-background-color: white;" + 1064 | "-fx-background-radius: 20px"); 1065 | exitBtnPane.setStyle("-fx-background-color: white;" + 1066 | "-fx-background-radius: 20px"); 1067 | minimizeBtnPane.setStyle("-fx-background-color: white;" + 1068 | "-fx-background-radius: 20px"); 1069 | 1070 | txtBack.setStyle("-fx-fill: #009CFF"); 1071 | txtClose.setStyle("-fx-fill: #009CFF"); 1072 | txtMinimize.setStyle("-fx-fill: #009CFF"); 1073 | 1074 | emojiPane.setVisible(false); 1075 | circleDarkTheme.setVisible(false); 1076 | circleLightTheme.setVisible(true); 1077 | } 1078 | 1079 | private void setDarkTheme() { 1080 | imgChatRoomBackground.setImage(new Image("assests/image/chatRoomBackgroundDark.png")); 1081 | imgPlayTechLogo.setImage(new Image("assests/image/playTechLogoChatRoomDark.png")); 1082 | imgDarkTheme.setImage(new Image("assests/icon/nightThemeIconSilver.png")); 1083 | imgLightTheme.setImage(new Image("assests/icon/lightThemeIconSilver.png")); 1084 | imgSendBtn.setImage(new Image("assests/icon/sendBtnIconSilver.png")); 1085 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 1086 | imgCloseIcon.setImage(new Image("assests/icon/closeIconSilver.png")); 1087 | imgMinimizeIcon.setImage(new Image("assests/icon/minimizeIconSilver.png")); 1088 | imgBackIcon.setImage(new Image("assests/icon/backBtnIconSilver.png")); 1089 | 1090 | // Apply styles directly to vertical scroll bar 1091 | scrollPane.lookup(".scroll-bar:vertical .thumb"). 1092 | setStyle("-fx-background-color: #A9A9A9; -fx-background-radius: 5em;"); 1093 | scrollPane.lookup(".scroll-bar:vertical .track"). 1094 | setStyle("-fx-background-color: #001F3F; -fx-border-color: #001F3F;"); 1095 | scrollPane.lookup(".increment-button"). 1096 | setStyle("-fx-background-color: #001F3F; -fx-border-color: #001F3F;"); 1097 | scrollPane.lookup(".decrement-button"). 1098 | setStyle("-fx-background-color: #001F3F; -fx-border-color: #001F3F;"); 1099 | 1100 | themeChangePane.setStyle("-fx-background-color: #A9A9A9;" + 1101 | "-fx-background-radius: 25px"); 1102 | 1103 | txtLogoChatRoom.setStyle("-fx-fill: #A9A9A9"); 1104 | lblUsername.setStyle("-fx-text-fill: #cbcbcb"); 1105 | circleOnlineIndicator.setStyle("-fx-fill: #001F3F;" + 1106 | "-fx-stroke: #cbcbcb;" + 1107 | "-fx-stroke-width: 3px"); 1108 | 1109 | vBox.setStyle("-fx-background-color: #001F3F"); 1110 | scrollPane.setStyle("-fx-background-color: #001F3F;" + 1111 | "-fx-control-inner-background: #001F3F;" + 1112 | "-fx-background: #001F3F;"); 1113 | 1114 | messageAreaPane.setStyle("-fx-background-color: #001F3F;" + 1115 | "-fx-background-radius: 16px"); 1116 | 1117 | txtMessage.setStyle("-fx-background-color: #001F3F;" + 1118 | "-fx-control-inner-background: #F0F0F0;" + 1119 | "-fx-background: #001F3F;" + 1120 | "-fx-text-fill: #F0F0F0;"); 1121 | 1122 | txtMessagePane.setStyle("-fx-background-color: #001F3F;" + 1123 | "-fx-background-radius: 25px"); 1124 | 1125 | sendBtnInnerPane.setStyle("-fx-background-color: #001F3F;" + 1126 | "-fx-background-radius: 25px"); 1127 | sendBtnOuterPane.setStyle("-fx-background-color: #A9A9A9;" + 1128 | "-fx-background-radius: 25px"); 1129 | 1130 | emojiPane.setStyle("-fx-background-color: #001F3F;" + 1131 | "-fx-border-color: #A9A9A9;" + 1132 | "-fx-background-radius: 18px;" + 1133 | "-fx-border-radius: 18px"); 1134 | 1135 | circleCloseIconOuter.setStyle("-fx-fill: #A9A9A9"); 1136 | circleCloseIconInner.setStyle("-fx-fill: #001F3F;" + 1137 | "-fx-stroke: #001F3F"); 1138 | 1139 | circleMinimizeIconOuter.setStyle("-fx-fill: #A9A9A9"); 1140 | circleMinimizeIconInner.setStyle("-fx-fill: #001F3F;" + 1141 | "-fx-stroke: #001F3F"); 1142 | 1143 | backBtnPane.setStyle("-fx-background-color: #CBCBCB;" + 1144 | "-fx-background-radius: 20px"); 1145 | exitBtnPane.setStyle("-fx-background-color: #CBCBCB;" + 1146 | "-fx-background-radius: 20px"); 1147 | minimizeBtnPane.setStyle("-fx-background-color: #CBCBCB;" + 1148 | "-fx-background-radius: 20px"); 1149 | 1150 | txtBack.setStyle("-fx-fill: #001F3F"); 1151 | txtClose.setStyle("-fx-fill: #001F3F"); 1152 | txtMinimize.setStyle("-fx-fill: #001F3F"); 1153 | 1154 | emojiPane.setVisible(false); 1155 | circleLightTheme.setVisible(false); 1156 | circleDarkTheme.setVisible(true); 1157 | } 1158 | 1159 | private void changeTheme() { 1160 | if (circleLightTheme.isVisible()) { 1161 | setDarkTheme(); 1162 | } else { 1163 | setLightTheme(); 1164 | } 1165 | } 1166 | 1167 | @FXML 1168 | void themeChangeBtnOnAction(ActionEvent event) { 1169 | changeTheme(); 1170 | } 1171 | } 1172 | -------------------------------------------------------------------------------- /Client_02/src/main/java/lk/ijse/liveChatRoom/controller/ChatRoomFormController.java: -------------------------------------------------------------------------------- 1 | package lk.ijse.liveChatRoom.controller; 2 | 3 | import com.jfoenix.controls.JFXButton; 4 | import javafx.application.Platform; 5 | import javafx.event.ActionEvent; 6 | import javafx.fxml.FXML; 7 | import javafx.geometry.Insets; 8 | import javafx.geometry.Pos; 9 | import javafx.scene.Node; 10 | import javafx.scene.control.Label; 11 | import javafx.scene.control.ScrollPane; 12 | import javafx.scene.control.TextField; 13 | import javafx.scene.image.Image; 14 | import javafx.scene.image.ImageView; 15 | import javafx.scene.input.KeyEvent; 16 | import javafx.scene.input.MouseEvent; 17 | import javafx.scene.layout.HBox; 18 | import javafx.scene.layout.Pane; 19 | import javafx.scene.layout.VBox; 20 | import javafx.scene.paint.Color; 21 | import javafx.scene.shape.Circle; 22 | import javafx.scene.text.Font; 23 | import javafx.scene.text.Text; 24 | import javafx.scene.text.TextFlow; 25 | import javafx.stage.FileChooser; 26 | import lk.ijse.liveChatRoom.util.NavigationUtil; 27 | import lk.ijse.liveChatRoom.util.TransitionUtil; 28 | 29 | import java.io.*; 30 | import java.net.Socket; 31 | import java.nio.file.Files; 32 | import java.time.LocalDateTime; 33 | import java.time.format.DateTimeFormatter; 34 | import java.util.Base64; 35 | import java.util.Random; 36 | import java.util.regex.Pattern; 37 | 38 | public class ChatRoomFormController { 39 | 40 | @FXML 41 | private Circle circleCloseIconInner; 42 | 43 | @FXML 44 | private Circle circleCloseIconOuter; 45 | 46 | @FXML 47 | private Circle circleMinimizeIconInner; 48 | 49 | @FXML 50 | private Circle circleMinimizeIconOuter; 51 | 52 | @FXML 53 | private Circle circleOnlineIndicator; 54 | 55 | @FXML 56 | private Circle circleDarkTheme; 57 | 58 | @FXML 59 | private Circle circleLightTheme; 60 | 61 | @FXML 62 | private ImageView imgBackIcon; 63 | 64 | @FXML 65 | private ImageView imgCloseIcon; 66 | 67 | @FXML 68 | private ImageView imgMinimizeIcon; 69 | 70 | @FXML 71 | private ImageView imgDarkTheme; 72 | 73 | @FXML 74 | private ImageView imgLightTheme; 75 | 76 | @FXML 77 | private ImageView imgPlayTechLogo; 78 | 79 | @FXML 80 | private ImageView imgChatRoomBackground; 81 | 82 | @FXML 83 | private ImageView imgSendBtn; 84 | 85 | @FXML 86 | private ImageView imgAttachIcon; 87 | 88 | @FXML 89 | private ImageView imgEmojiIcon; 90 | 91 | @FXML 92 | private ImageView imgAnxiousFaceWithSweatEmoji; 93 | 94 | @FXML 95 | private ImageView imgCryingFaceEmoji; 96 | 97 | @FXML 98 | private ImageView imgDisappointedFaceEmoji; 99 | 100 | @FXML 101 | private ImageView imgExpressionlessFaceEmoji; 102 | 103 | @FXML 104 | private ImageView imgFaceWithTearsOfJoyEmoji; 105 | 106 | @FXML 107 | private ImageView imgFaceWithTongueEmoji; 108 | 109 | @FXML 110 | private ImageView imgFearfulFaceEmoji; 111 | 112 | @FXML 113 | private ImageView imgGrinningFaceEmoji; 114 | 115 | @FXML 116 | private ImageView imgHushedFaceEmoji; 117 | 118 | @FXML 119 | private ImageView imgLoudlyCryingEmoji; 120 | 121 | @FXML 122 | private ImageView imgLoveHeartsEyesEmoji; 123 | 124 | @FXML 125 | private ImageView imgSleepingFaceEmoji; 126 | 127 | @FXML 128 | private ImageView imgSmilingFaceEmoji; 129 | 130 | @FXML 131 | private ImageView imgSmilingFaceWithHaloEmoji; 132 | 133 | @FXML 134 | private ImageView imgSmilingFaceWithSunglassesEmoji; 135 | 136 | @FXML 137 | private ImageView imgThumbUpEmoji; 138 | 139 | @FXML 140 | private ImageView imgThumbsDownEmoji; 141 | 142 | @FXML 143 | private ImageView imgWinkingFaceEmoji; 144 | 145 | @FXML 146 | private JFXButton backBtn; 147 | 148 | @FXML 149 | private Pane themeChangePane; 150 | 151 | @FXML 152 | private Pane txtMessagePane; 153 | 154 | @FXML 155 | private Pane messageAreaPane; 156 | 157 | @FXML 158 | private Pane sendBtnInnerPane; 159 | 160 | @FXML 161 | private Pane sendBtnOuterPane; 162 | 163 | @FXML 164 | private Pane emojiPane; 165 | 166 | @FXML 167 | private Pane exitBtnPane; 168 | 169 | @FXML 170 | private Pane backBtnPane; 171 | 172 | @FXML 173 | private Pane minimizeBtnPane; 174 | 175 | @FXML 176 | private Label lblUsername; 177 | 178 | @FXML 179 | private Label lblMessageTextAlert; 180 | 181 | @FXML 182 | private ScrollPane scrollPane; 183 | 184 | @FXML 185 | private TextField txtMessage; 186 | 187 | @FXML 188 | private Text txtBack; 189 | 190 | @FXML 191 | private Text txtClose; 192 | 193 | @FXML 194 | private Text txtMinimize; 195 | 196 | @FXML 197 | private Text txtLogoChatRoom; 198 | 199 | @FXML 200 | private VBox vBox; 201 | 202 | private Socket remoteSocket; 203 | private File file; 204 | private String base64Image; 205 | private PrintWriter printWriter; 206 | private BufferedReader bufferedReader; 207 | private String finalName; 208 | 209 | public void initialize() { 210 | lblUsername.setText(LoginFormController.username); 211 | new Thread(()->{ 212 | try { 213 | remoteSocket = new Socket("localhost", 3400); 214 | System.out.println("Client: "+lblUsername.getText()+" Connected!"); 215 | 216 | bufferedReader = new BufferedReader(new InputStreamReader(remoteSocket.getInputStream())); 217 | printWriter = new PrintWriter(remoteSocket.getOutputStream(),true); //like dataOutputStream 218 | 219 | printWriter.println("joi"+lblUsername.getText()+": joining..."); 220 | 221 | while (true) { 222 | //reading the response 223 | String receivedFullMsg = bufferedReader.readLine(); 224 | String[] splitTheMsg = receivedFullMsg.split(":"); 225 | String username = splitTheMsg[0]; 226 | String message = splitTheMsg[1]; 227 | 228 | //finding the arrived message type 229 | String firstCharacter = findingTheArrivedMessageType(username); 230 | 231 | //remove the username prefixes (if available) 232 | removePrefixes(username, firstCharacter); 233 | 234 | //if an Image arrived 235 | if (firstCharacter.equalsIgnoreCase("img")) { 236 | setImage(receivedFullMsg); 237 | } 238 | 239 | // display new client who join the chat 240 | else if (firstCharacter.equalsIgnoreCase("joi")){ 241 | HBox hBox = new HBox(); 242 | if (lblUsername.getText().equals(finalName)) { 243 | Label joinText = new Label("You have joined the Chat"); 244 | 245 | hBox.getChildren().add(joinText); 246 | hBox.setAlignment(Pos.CENTER); 247 | hBox.setPadding(new Insets(5,5,5,10)); 248 | } 249 | else { 250 | Label joinText = new Label(finalName+" has joined the Chat"); 251 | hBox.getChildren().add(joinText); 252 | hBox.setAlignment(Pos.CENTER); 253 | hBox.setPadding(new Insets(5,5,5,10)); 254 | } 255 | 256 | Platform.runLater(() -> 257 | vBox.getChildren().addAll(hBox)); 258 | } 259 | // display the client who left the chat 260 | else if (firstCharacter.equalsIgnoreCase("lef")) { 261 | Label leftText = new Label(finalName + " has left the Chat"); 262 | 263 | HBox hBox = new HBox(); 264 | hBox.getChildren().add(leftText); 265 | hBox.setAlignment(Pos.CENTER); 266 | hBox.setPadding(new Insets(5, 5, 5, 10)); 267 | 268 | Platform.runLater(() -> 269 | vBox.getChildren().add(hBox)); 270 | } 271 | else { 272 | if (lblUsername.getText().equalsIgnoreCase(username)) { 273 | sendMessage(message); 274 | } else { 275 | receivedMessage(receivedFullMsg); 276 | } 277 | } 278 | } 279 | } catch (IOException e) { 280 | e.printStackTrace(); 281 | } 282 | }).start(); 283 | } 284 | 285 | private HBox setTime() { 286 | DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm"); 287 | LocalDateTime now = LocalDateTime.now(); 288 | 289 | Text time = new Text(dateTimeFormatter.format(now)); 290 | time.setFont(Font.font(10)); 291 | 292 | HBox timeBox = new HBox(); 293 | timeBox.getChildren().add(time); 294 | timeBox.setAlignment(Pos.BOTTOM_RIGHT); 295 | 296 | return timeBox; 297 | } 298 | 299 | private void removePrefixes(String username, String firstCharacter) { 300 | if (firstCharacter.equalsIgnoreCase("img")) { 301 | String[] name = username.split("img"); //to remove prefix "img" 302 | finalName = name[1]; 303 | } 304 | else if (firstCharacter.equalsIgnoreCase("joi")) { 305 | String[] name = username.split("joi"); //to remove prefix "joi" 306 | finalName = name[1]; 307 | } 308 | else if (firstCharacter.equalsIgnoreCase("lef")) { 309 | String[] name = username.split("lef"); //to remove prefix "lef" 310 | finalName = name[1]; 311 | } 312 | } 313 | 314 | private String findingTheArrivedMessageType(String username) { 315 | String firstCharacter = ""; 316 | if (username.length() > 3) { 317 | firstCharacter = username.substring(0, 3); 318 | System.out.println("First Char: " + firstCharacter); 319 | } 320 | return firstCharacter; 321 | } 322 | 323 | private File decodeReceivedImage(String path) throws IOException { 324 | byte[] imageBytes = Base64.getDecoder().decode(path); // Decode Base64 image data 325 | 326 | // Set file path & create a file to save the received image 327 | int randomNumber = new Random().nextInt(1000000); 328 | String fileName = "ReceivedImage_" + randomNumber + ".png"; 329 | File directoryPath = new File("Client_02/src/main/resources/receivedImages"); 330 | File receivedImageFile = new File(directoryPath, fileName); 331 | 332 | // Write the image bytes to the file 333 | try (FileOutputStream fos = new FileOutputStream(receivedImageFile)) { 334 | fos.write(imageBytes); 335 | } 336 | return receivedImageFile; 337 | } 338 | 339 | private void setImage(String receivedFullMsg) throws IOException { 340 | String[] splitMessage = receivedFullMsg.split(":"); 341 | String path = splitMessage[1]; 342 | System.out.println("Message Path :" + path); 343 | 344 | File receivedImageFile = decodeReceivedImage(path); 345 | 346 | Image receivedImage = new Image(receivedImageFile.toURI().toString()); 347 | 348 | ImageView imageView = new ImageView(receivedImage); 349 | imageView.setFitHeight(300); 350 | imageView.setFitWidth(300); 351 | imageView.setPreserveRatio(true); 352 | 353 | HBox imageBox = new HBox(imageView); 354 | imageBox.setPadding(new Insets(5)); 355 | 356 | HBox hBox = new HBox(10); 357 | hBox.setAlignment(Pos.BOTTOM_RIGHT); 358 | 359 | // Created an inner HBox to contain both the imageHBox and timeHBox 360 | HBox innerHBox = new HBox(); 361 | innerHBox.setPadding(new Insets(5,10,5,10)); 362 | 363 | // Add time 364 | HBox timeBox = setTime(); 365 | 366 | //if received Image selected by me 367 | if (lblUsername.getText().equalsIgnoreCase(finalName)) { 368 | // Set color for the Text within the timeBox 369 | for (Node node : timeBox.getChildren()) { 370 | if (node instanceof Text) { 371 | ((Text) node).setFill(Color.color(0.934, 0.945, 0.996)); 372 | } 373 | } 374 | 375 | if (circleLightTheme.isVisible()) { 376 | innerHBox.setStyle( 377 | "-fx-background-color: rgb(15,125,242);" + 378 | "-fx-background-radius: 20px" 379 | ); 380 | } else { 381 | innerHBox.setStyle( 382 | "-fx-background-color: rgb(8, 78, 153);" + 383 | "-fx-background-radius: 20px" 384 | ); 385 | } 386 | 387 | innerHBox.getChildren().addAll(imageBox,timeBox); 388 | 389 | hBox.getChildren().add(innerHBox); 390 | hBox.setAlignment(Pos.TOP_RIGHT); 391 | hBox.setPadding(new Insets(5,5,5,10)); //set space between images 392 | } 393 | 394 | //if received Image selected by another client 395 | else { 396 | if (circleLightTheme.isVisible()) { 397 | innerHBox.setStyle( 398 | "-fx-background-color: rgb(233,233,235);" + 399 | "-fx-background-radius: 20px" 400 | ); 401 | } else { 402 | innerHBox.setStyle( 403 | "-fx-background-color: #A9A9A9;" + 404 | "-fx-background-radius: 20px" 405 | ); 406 | } 407 | 408 | vBox.setAlignment(Pos.TOP_LEFT); 409 | hBox.setAlignment(Pos.TOP_LEFT); 410 | 411 | Text text = new Text(" " + finalName + " :"); 412 | text.setFont(Font.font(12.5)); 413 | 414 | innerHBox.getChildren().addAll(text,imageBox,timeBox); 415 | hBox.getChildren().add(innerHBox); 416 | hBox.setPadding(new Insets(5,5,5,10)); 417 | } 418 | 419 | Platform.runLater(() -> { 420 | vBox.getChildren().add(hBox); 421 | scrollPane.layout(); // Ensure layout is updated 422 | scrollPane.setVvalue(1.0); // Scroll down to the bottom 423 | }); 424 | } 425 | 426 | private void sendMessage(String messageToSend) { 427 | if (!messageToSend.isEmpty()) { 428 | HBox hBox = new HBox(); 429 | hBox.setAlignment(Pos.CENTER_RIGHT); 430 | hBox.setPadding(new Insets(5,10,5,10)); 431 | 432 | // Created an inner HBox to contain both the message and time 433 | HBox innerHBox = new HBox(); 434 | innerHBox.setPadding(new Insets(2,10,2.5,10)); 435 | 436 | Text text = new Text(messageToSend); 437 | text.setFont(Font.font(17)); 438 | TextFlow textFlow = new TextFlow(text); 439 | 440 | if (circleLightTheme.isVisible()) { 441 | innerHBox.setStyle( 442 | "-fx-background-color: rgb(15,125,242);" + 443 | "-fx-background-radius: 20px" 444 | ); 445 | } else { 446 | innerHBox.setStyle( 447 | "-fx-background-color: rgb(8, 78, 153);" + 448 | "-fx-background-radius: 20px" 449 | ); 450 | } 451 | 452 | textFlow.setPadding(new Insets(5,10,5,10)); 453 | text.setFill(Color.color(0.934, 0.945, 0.996)); 454 | 455 | // Add time 456 | HBox timeBox = setTime(); 457 | 458 | // Set color for the Text within the timeBox 459 | for (Node node : timeBox.getChildren()) { 460 | if (node instanceof Text) { 461 | ((Text) node).setFill(Color.color(0.934, 0.945, 0.996)); 462 | } 463 | } 464 | 465 | innerHBox.getChildren().addAll(textFlow, timeBox); 466 | hBox.getChildren().add(innerHBox); 467 | 468 | Platform.runLater(new Runnable() { 469 | @Override 470 | public void run() { 471 | vBox.getChildren().add(hBox); 472 | scrollPane.layout(); // Ensure layout is updated 473 | scrollPane.setVvalue(1.0); // Scroll down to the bottom 474 | } 475 | }); 476 | } 477 | } 478 | 479 | private void receivedMessage(String receivedMsg) { 480 | String[] name = receivedMsg.split(":"); 481 | String username = name[0]; 482 | String message = name[1]; 483 | 484 | if (!lblUsername.getText().equals(username)) { 485 | HBox hBox = new HBox(); 486 | hBox.setAlignment(Pos.CENTER_LEFT); 487 | hBox.setPadding(new Insets(5,5,5,10)); 488 | 489 | // Created an inner HBox to contain both the message and time 490 | HBox innerHBox = new HBox(); 491 | innerHBox.setPadding(new Insets(2,10,2.5,5)); 492 | 493 | Text txtUsername = new Text(username + ": "); 494 | txtUsername.setFont(Font.font(12.5)); 495 | 496 | Text txtMessage = new Text(message); 497 | txtMessage.setFont(Font.font(17)); 498 | 499 | TextFlow textFlow = new TextFlow(txtUsername, txtMessage); 500 | 501 | if (circleLightTheme.isVisible()) { 502 | innerHBox.setStyle( 503 | "-fx-background-color: rgb(233,233,235);" + 504 | "-fx-background-radius: 20px" 505 | ); 506 | } else { 507 | innerHBox.setStyle( 508 | "-fx-background-color: #A9A9A9;" + 509 | "-fx-background-radius: 20px" 510 | ); 511 | } 512 | 513 | textFlow.setPadding(new Insets(5,10,5,10)); 514 | 515 | // Add time 516 | HBox timeBox = setTime(); 517 | 518 | innerHBox.getChildren().addAll(textFlow, timeBox); 519 | hBox.getChildren().add(innerHBox); 520 | 521 | Platform.runLater(() -> { 522 | vBox.getChildren().add(hBox); 523 | scrollPane.layout(); 524 | scrollPane.setVvalue(1.0); 525 | }); 526 | } 527 | } 528 | 529 | @FXML 530 | void btnAttachOnAction(ActionEvent event) throws IOException { 531 | lblMessageTextAlert.setText(" "); 532 | FileChooser fileChooser = new FileChooser(); 533 | fileChooser.setTitle("Select an Image!!"); 534 | 535 | FileChooser.ExtensionFilter imageFilter = 536 | new FileChooser.ExtensionFilter("Image Files","*.jpg","*.jpeg","*.png","*.gif"); 537 | 538 | fileChooser.getExtensionFilters().add(imageFilter); 539 | file = fileChooser.showOpenDialog(txtMessage.getScene().getWindow()); 540 | 541 | if (file != null) { 542 | txtMessage.setText("01 Image Selected"); 543 | txtMessage.setEditable(false); 544 | 545 | // Read image file into byte array 546 | byte[] imageBytes = Files.readAllBytes(file.toPath()); 547 | base64Image = Base64.getEncoder().encodeToString(imageBytes); 548 | 549 | btnSendOnAction(event); 550 | imgAttachIcon.setImage(new Image("assests/icon/attachmentIcon.png")); 551 | } 552 | } 553 | 554 | @FXML 555 | void btnAttachOnMouseEntered(MouseEvent event) { 556 | imgAttachIcon.setImage(new Image("assests/icon/attachmentIconBlue.png")); 557 | } 558 | 559 | @FXML 560 | void btnAttachOnMouseExited(MouseEvent event) { 561 | imgAttachIcon.setImage(new Image("assests/icon/attachmentIcon.png")); 562 | } 563 | 564 | @FXML 565 | void btnEmojiOnAction(ActionEvent event) { 566 | lblMessageTextAlert.setText(" "); 567 | emojiPane.setVisible(!emojiPane.isVisible()); 568 | if (emojiPane.isVisible()) { 569 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIconBlue.png")); 570 | } else { 571 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 572 | } 573 | } 574 | 575 | @FXML 576 | void btnEmojiOnMouseEntered(MouseEvent event) { 577 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIconBlue.png")); 578 | } 579 | 580 | @FXML 581 | void btnEmojiOnMouseExited(MouseEvent event) { 582 | if (!emojiPane.isVisible()) { 583 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 584 | } 585 | } 586 | 587 | @FXML 588 | void btnBackOnAction(ActionEvent event) throws IOException { 589 | printWriter.println("lef" + lblUsername.getText() + ": leaving"); 590 | NavigationUtil.switchNavigation("loginForm.fxml",event); 591 | } 592 | 593 | @FXML 594 | void btnExitOnAction(ActionEvent event) { 595 | printWriter.println("lef" + lblUsername.getText() + ": leaving"); 596 | NavigationUtil.exit(); 597 | } 598 | 599 | @FXML 600 | void btnMinimizeOnAction(ActionEvent event) { 601 | NavigationUtil.minimize(); 602 | } 603 | 604 | @FXML 605 | void btnExitOnMouseEntered(MouseEvent event) { 606 | exitBtnPane.setVisible(true); 607 | TransitionUtil.ScaleTransition(exitBtnPane); 608 | } 609 | 610 | @FXML 611 | void btnExitOnMouseExited(MouseEvent event) { 612 | exitBtnPane.setVisible(false); 613 | } 614 | 615 | @FXML 616 | void btnMinimizeOnMouseEntered(MouseEvent event) { 617 | minimizeBtnPane.setVisible(true); 618 | TransitionUtil.ScaleTransition(minimizeBtnPane); 619 | } 620 | 621 | @FXML 622 | void btnMinimizeOnMouseExited(MouseEvent event) { 623 | minimizeBtnPane.setVisible(false); 624 | } 625 | 626 | @FXML 627 | void btnBackOnMouseEntered(MouseEvent event) { 628 | backBtnPane.setVisible(true); 629 | TransitionUtil.ScaleTransition(backBtnPane); 630 | if (circleLightTheme.isVisible()) { 631 | backBtn.setStyle( 632 | "-fx-border-color: white;" + 633 | "-fx-border-width: 3px;" + 634 | "-fx-border-radius: 50px"); 635 | } else { 636 | backBtn.setStyle( 637 | "-fx-border-color: #CBCBCB;" + 638 | "-fx-border-width: 3px;" + 639 | "-fx-border-radius: 50px"); 640 | } 641 | } 642 | 643 | @FXML 644 | void btnBackOnMouseExited(MouseEvent event) { 645 | backBtn.setStyle("-fx-border-color: transparent"); 646 | backBtnPane.setVisible(false); 647 | } 648 | 649 | @FXML 650 | void btnSendOnAction(ActionEvent event) { 651 | if (validateMessage()){ 652 | if (file != null) { 653 | printWriter.println("img"+lblUsername.getText() +":"+ base64Image); 654 | file = null; 655 | } else { 656 | printWriter.println(lblUsername.getText() + ": " + txtMessage.getText()); 657 | } 658 | txtMessage.setEditable(true); 659 | emojiPane.setVisible(false); 660 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 661 | txtMessage.clear(); 662 | } 663 | else { 664 | lblMessageTextAlert.setText("Message should have at least a character!!"); 665 | } 666 | } 667 | 668 | private boolean validateMessage() { 669 | return Pattern.matches("^.+$", txtMessage.getText()); 670 | } 671 | 672 | @FXML 673 | void btnSendOnMouseEntered(MouseEvent event) { 674 | TransitionUtil.ScaleTransition(imgSendBtn, 1.1); 675 | if (circleLightTheme.isVisible()) { 676 | sendBtnInnerPane.setStyle( 677 | "-fx-background-color: #018DE7;" + 678 | "-fx-background-radius: 25px"); 679 | } else { 680 | sendBtnInnerPane.setStyle( 681 | "-fx-background-color: #001727;" + 682 | "-fx-background-radius: 25px"); 683 | } 684 | } 685 | 686 | @FXML 687 | void btnSendOnMouseExited(MouseEvent event) { 688 | TransitionUtil.ScaleTransition(imgSendBtn, 1.0); 689 | if (circleLightTheme.isVisible()) { 690 | sendBtnInnerPane.setStyle( 691 | "-fx-background-color: #009CFF;" + 692 | "-fx-background-radius: 25px"); 693 | } else { 694 | sendBtnInnerPane.setStyle( 695 | "-fx-background-color: #001F3F;" + 696 | "-fx-background-radius: 25px"); 697 | } 698 | } 699 | 700 | @FXML 701 | void txtMessageOnAction(ActionEvent event) { 702 | btnSendOnAction(event); 703 | } 704 | 705 | @FXML 706 | void txtMessageOnKeyPressed(KeyEvent event) { 707 | if (!txtMessage.getText().isEmpty()) { 708 | lblMessageTextAlert.setText(" "); 709 | } 710 | } 711 | 712 | @FXML 713 | void imgAnxiousFaceWithSweatEmojiOnMouseClicked(MouseEvent event) { 714 | txtMessage.appendText("\uD83D\uDE30"); //😰 715 | finalizeEmojiSelection(event); 716 | } 717 | 718 | @FXML 719 | void imgCryingFaceEmojiOnMouseClicked(MouseEvent event) { 720 | txtMessage.appendText("\uD83D\uDE22"); //😢 721 | finalizeEmojiSelection(event); 722 | } 723 | 724 | @FXML 725 | void imgDisappointedFaceEmojiOnMouseClicked(MouseEvent event) { 726 | txtMessage.appendText("\uD83D\uDE1E"); //😞 727 | finalizeEmojiSelection(event); 728 | } 729 | 730 | @FXML 731 | void imgFaceWithTearsOfJoyEmojiOnMouseClicked(MouseEvent event) { 732 | txtMessage.appendText("\uD83D\uDE02"); //😂 733 | finalizeEmojiSelection(event); 734 | } 735 | 736 | @FXML 737 | void imgFaceWithTongueEmojiOnMouseClicked(MouseEvent event) { 738 | txtMessage.appendText("\uD83D\uDE1B"); //😛 739 | finalizeEmojiSelection(event); 740 | } 741 | 742 | @FXML 743 | void imgFearfulFaceEmojiOnMouseClicked(MouseEvent event) { 744 | txtMessage.appendText("\uD83D\uDE28"); //😦 745 | finalizeEmojiSelection(event); 746 | } 747 | 748 | @FXML 749 | void imgGrinningFaceEmojiOnMouseClicked(MouseEvent event) { 750 | txtMessage.appendText("\uD83D\uDE00"); //😀 751 | finalizeEmojiSelection(event); 752 | } 753 | 754 | @FXML 755 | void imgHushedFaceEmojiOnMouseClicked(MouseEvent event) { 756 | txtMessage.appendText("\uD83D\uDE2F"); //😯 757 | finalizeEmojiSelection(event); 758 | } 759 | 760 | @FXML 761 | void imgLoudlyCryingEmojiOnMouseClicked(MouseEvent event) { 762 | txtMessage.appendText("\uD83D\uDE2D"); //😭 763 | finalizeEmojiSelection(event); 764 | } 765 | 766 | @FXML 767 | void imgLoveHeartsEyesEmojiOnMouseClicked(MouseEvent event) { 768 | txtMessage.appendText("\uD83D\uDE0D"); //😍 769 | finalizeEmojiSelection(event); 770 | } 771 | 772 | @FXML 773 | void imgExpressionlessFaceEmojiOnMouseClicked(MouseEvent event) { 774 | txtMessage.appendText("\uD83D\uDE11"); //😑 775 | finalizeEmojiSelection(event); 776 | } 777 | 778 | @FXML 779 | void imgSleepingFaceEmojiOnMouseClicked(MouseEvent event) { 780 | txtMessage.appendText("\uD83D\uDE34"); //😴 781 | finalizeEmojiSelection(event); 782 | } 783 | 784 | @FXML 785 | void imgSmilingFaceWithSunglassesEmojiOnMouseClicked(MouseEvent event) { 786 | txtMessage.appendText("\uD83D\uDE0E"); //😎 787 | finalizeEmojiSelection(event); 788 | } 789 | 790 | @FXML 791 | void imgSmilingFaceEmojiOnMouseClicked(MouseEvent event) { 792 | txtMessage.appendText("\uD83D\uDE0A"); //😊 793 | finalizeEmojiSelection(event); 794 | } 795 | 796 | @FXML 797 | void imgSmilingFaceWithHaloEmojiOnMouseClicked(MouseEvent event) { 798 | txtMessage.appendText("\uD83D\uDE07"); //😇 799 | finalizeEmojiSelection(event); 800 | } 801 | 802 | @FXML 803 | void imgThumbsDownEmojiOnMouseClicked(MouseEvent event) { 804 | txtMessage.appendText("\uD83D\uDC4E"); //👎 805 | finalizeEmojiSelection(event); 806 | } 807 | 808 | @FXML 809 | void imgThumbUpEmojiOnMouseClicked(MouseEvent event) { 810 | txtMessage.appendText("\uD83D\uDC4D"); //👍 811 | finalizeEmojiSelection(event); 812 | } 813 | 814 | @FXML 815 | void imgWinkingFaceEmojiOnMouseClicked(MouseEvent event) { 816 | txtMessage.appendText("\uD83D\uDE09"); //😉 817 | finalizeEmojiSelection(event); 818 | } 819 | 820 | private void finalizeEmojiSelection(MouseEvent event) { 821 | emojiPane.setVisible(false); 822 | btnEmojiOnMouseExited(event); 823 | txtMessage.requestFocus(); 824 | } 825 | 826 | @FXML 827 | void imgAnxiousFaceWithSweatEmojiOnMouseEntered(MouseEvent event) { 828 | TransitionUtil.ScaleTransition(imgAnxiousFaceWithSweatEmoji, 1.2); 829 | } 830 | 831 | @FXML 832 | void imgAnxiousFaceWithSweatEmojiOnMouseExited(MouseEvent event) { 833 | TransitionUtil.ScaleTransition(imgAnxiousFaceWithSweatEmoji, 1.0); 834 | } 835 | 836 | @FXML 837 | void imgCryingFaceEmojiOnMouseEntered(MouseEvent event) { 838 | TransitionUtil.ScaleTransition(imgCryingFaceEmoji, 1.2); 839 | } 840 | 841 | @FXML 842 | void imgCryingFaceEmojiOnMouseExited(MouseEvent event) { 843 | TransitionUtil.ScaleTransition(imgCryingFaceEmoji, 1.0); 844 | } 845 | 846 | @FXML 847 | void imgDisappointedFaceEmojiOnMouseEntered(MouseEvent event) { 848 | TransitionUtil.ScaleTransition(imgDisappointedFaceEmoji, 1.2); 849 | } 850 | 851 | @FXML 852 | void imgDisappointedFaceEmojiOnMouseExited(MouseEvent event) { 853 | TransitionUtil.ScaleTransition(imgDisappointedFaceEmoji, 1.0); 854 | } 855 | 856 | @FXML 857 | void imgExpressionlessFaceEmojiOnMouseEntered(MouseEvent event) { 858 | TransitionUtil.ScaleTransition(imgExpressionlessFaceEmoji, 1.2); 859 | } 860 | 861 | @FXML 862 | void imgExpressionlessFaceEmojiOnMouseExited(MouseEvent event) { 863 | TransitionUtil.ScaleTransition(imgExpressionlessFaceEmoji, 1.0); 864 | } 865 | 866 | @FXML 867 | void imgFaceWithTearsOfJoyEmojiOnMouseEntered(MouseEvent event) { 868 | TransitionUtil.ScaleTransition(imgFaceWithTearsOfJoyEmoji, 1.2); 869 | } 870 | 871 | @FXML 872 | void imgFaceWithTearsOfJoyEmojiOnMouseExited(MouseEvent event) { 873 | TransitionUtil.ScaleTransition(imgFaceWithTearsOfJoyEmoji, 1.0); 874 | } 875 | 876 | @FXML 877 | void imgFaceWithTongueEmojiOnMouseEntered(MouseEvent event) { 878 | TransitionUtil.ScaleTransition(imgFaceWithTongueEmoji, 1.2); 879 | } 880 | 881 | @FXML 882 | void imgFaceWithTongueEmojiOnMouseExited(MouseEvent event) { 883 | TransitionUtil.ScaleTransition(imgFaceWithTongueEmoji, 1.0); 884 | } 885 | 886 | @FXML 887 | void imgFearfulFaceEmojiOnMouseEntered(MouseEvent event) { 888 | TransitionUtil.ScaleTransition(imgFearfulFaceEmoji, 1.2); 889 | } 890 | 891 | @FXML 892 | void imgFearfulFaceEmojiOnMouseExited(MouseEvent event) { 893 | TransitionUtil.ScaleTransition(imgFearfulFaceEmoji, 1.0); 894 | } 895 | 896 | @FXML 897 | void imgGrinningFaceEmojiOnMouseEntered(MouseEvent event) { 898 | TransitionUtil.ScaleTransition(imgGrinningFaceEmoji, 1.2); 899 | } 900 | 901 | @FXML 902 | void imgGrinningFaceEmojiOnMouseExited(MouseEvent event) { 903 | TransitionUtil.ScaleTransition(imgGrinningFaceEmoji, 1.0); 904 | } 905 | 906 | @FXML 907 | void imgHushedFaceEmojiOnMouseEntered(MouseEvent event) { 908 | TransitionUtil.ScaleTransition(imgHushedFaceEmoji, 1.2); 909 | } 910 | 911 | @FXML 912 | void imgHushedFaceEmojiOnMouseExited(MouseEvent event) { 913 | TransitionUtil.ScaleTransition(imgHushedFaceEmoji, 1.0); 914 | } 915 | 916 | @FXML 917 | void imgLoudlyCryingEmojiOnMouseEntered(MouseEvent event) { 918 | TransitionUtil.ScaleTransition(imgLoudlyCryingEmoji, 1.2); 919 | } 920 | 921 | @FXML 922 | void imgLoudlyCryingEmojiOnMouseExited(MouseEvent event) { 923 | TransitionUtil.ScaleTransition(imgLoudlyCryingEmoji, 1.0); 924 | } 925 | 926 | @FXML 927 | void imgLoveHeartsEyesEmojiOnMouseEntered(MouseEvent event) { 928 | TransitionUtil.ScaleTransition(imgLoveHeartsEyesEmoji, 1.2); 929 | } 930 | 931 | @FXML 932 | void imgLoveHeartsEyesEmojiOnMouseExited(MouseEvent event) { 933 | TransitionUtil.ScaleTransition(imgLoveHeartsEyesEmoji, 1.0); 934 | } 935 | 936 | @FXML 937 | void imgSleepingFaceEmojiOnMouseEntered(MouseEvent event) { 938 | TransitionUtil.ScaleTransition(imgSleepingFaceEmoji, 1.2); 939 | } 940 | 941 | @FXML 942 | void imgSleepingFaceEmojiOnMouseExited(MouseEvent event) { 943 | TransitionUtil.ScaleTransition(imgSleepingFaceEmoji, 1.0); 944 | } 945 | 946 | @FXML 947 | void imgSmilingFaceEmojiOnMouseEntered(MouseEvent event) { 948 | TransitionUtil.ScaleTransition(imgSmilingFaceEmoji, 1.2); 949 | } 950 | 951 | @FXML 952 | void imgSmilingFaceEmojiOnMouseExited(MouseEvent event) { 953 | TransitionUtil.ScaleTransition(imgSmilingFaceEmoji, 1.0); 954 | } 955 | 956 | @FXML 957 | void imgSmilingFaceWithHaloEmojiOnMouseEntered(MouseEvent event) { 958 | TransitionUtil.ScaleTransition(imgSmilingFaceWithHaloEmoji, 1.2); 959 | } 960 | 961 | @FXML 962 | void imgSmilingFaceWithHaloEmojiOnMouseExited(MouseEvent event) { 963 | TransitionUtil.ScaleTransition(imgSmilingFaceWithHaloEmoji, 1.0); 964 | } 965 | 966 | @FXML 967 | void imgSmilingFaceWithSunglassesEmojiOnMouseEntered(MouseEvent event) { 968 | TransitionUtil.ScaleTransition(imgSmilingFaceWithSunglassesEmoji, 1.2); 969 | } 970 | 971 | @FXML 972 | void imgSmilingFaceWithSunglassesEmojiOnMouseExited(MouseEvent event) { 973 | TransitionUtil.ScaleTransition(imgSmilingFaceWithSunglassesEmoji, 1.0); 974 | } 975 | 976 | @FXML 977 | void imgThumbUpEmojiOnMouseEntered(MouseEvent event) { 978 | TransitionUtil.ScaleTransition(imgThumbUpEmoji, 1.2); 979 | } 980 | 981 | @FXML 982 | void imgThumbUpEmojiOnMouseExited(MouseEvent event) { 983 | TransitionUtil.ScaleTransition(imgThumbUpEmoji, 1.0); 984 | } 985 | 986 | @FXML 987 | void imgThumbsDownEmojiOnMouseEntered(MouseEvent event) { 988 | TransitionUtil.ScaleTransition(imgThumbsDownEmoji, 1.2); 989 | } 990 | 991 | @FXML 992 | void imgThumbsDownEmojiOnMouseExited(MouseEvent event) { 993 | TransitionUtil.ScaleTransition(imgThumbsDownEmoji, 1.0); 994 | } 995 | 996 | @FXML 997 | void imgWinkingFaceEmojiOnMouseEntered(MouseEvent event) { 998 | TransitionUtil.ScaleTransition(imgWinkingFaceEmoji, 1.2); 999 | } 1000 | 1001 | @FXML 1002 | void imgWinkingFaceEmojiOnMouseExited(MouseEvent event) { 1003 | TransitionUtil.ScaleTransition(imgWinkingFaceEmoji, 1.0); 1004 | } 1005 | 1006 | private void setLightTheme() { 1007 | imgChatRoomBackground.setImage(new Image("assests/image/chatRoomBackground.png")); 1008 | imgPlayTechLogo.setImage(new Image("assests/image/playTechLogoChatRoom.png")); 1009 | imgDarkTheme.setImage(new Image("assests/icon/nightThemeIcon.png")); 1010 | imgLightTheme.setImage(new Image("assests/icon/lightThemeIcon.png")); 1011 | imgSendBtn.setImage(new Image("assests/icon/sendBtnIcon.png")); 1012 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 1013 | imgCloseIcon.setImage(new Image("assests/icon/closeIcon.png")); 1014 | imgMinimizeIcon.setImage(new Image("assests/icon/minimizeIcon.png")); 1015 | imgBackIcon.setImage(new Image("assests/icon/backBtnIcon.png")); 1016 | 1017 | // Apply styles directly to vertical scroll bar 1018 | scrollPane.lookup(".scroll-bar:vertical .thumb"). 1019 | setStyle("-fx-background-color: #C0C0C0; -fx-background-radius: 5em;"); 1020 | scrollPane.lookup(".scroll-bar:vertical .track"). 1021 | setStyle("-fx-background-color: transparent; -fx-border-color: transparent;"); 1022 | scrollPane.lookup(".increment-button"). 1023 | setStyle("-fx-background-color: transparent; -fx-border-color: transparent;"); 1024 | scrollPane.lookup(".decrement-button"). 1025 | setStyle("-fx-background-color: transparent; -fx-border-color: transparent;"); 1026 | 1027 | themeChangePane.setStyle("-fx-background-color: white;" + 1028 | "-fx-background-radius: 25px"); 1029 | 1030 | txtLogoChatRoom.setStyle("-fx-fill: white"); 1031 | lblUsername.setStyle("-fx-text-fill: white"); 1032 | circleOnlineIndicator.setStyle("-fx-fill: #009CFF;" + 1033 | "-fx-stroke: white;" + 1034 | "-fx-stroke-width: 3px"); 1035 | 1036 | vBox.setStyle("-fx-background-color: white"); 1037 | scrollPane.setStyle("-fx-background-color: white"); 1038 | messageAreaPane.setStyle("-fx-background-color: white;" + 1039 | "-fx-background-radius: 16px"); 1040 | 1041 | txtMessage.setStyle("-fx-background-color: white"); 1042 | txtMessagePane.setStyle("-fx-background-color: white;" + 1043 | "-fx-background-radius: 25px"); 1044 | 1045 | sendBtnInnerPane.setStyle("-fx-background-color: #009CFF;" + 1046 | "-fx-background-radius: 25px"); 1047 | sendBtnOuterPane.setStyle("-fx-background-color: white;" + 1048 | "-fx-background-radius: 25px"); 1049 | 1050 | emojiPane.setStyle("-fx-background-color: white;" + 1051 | "-fx-border-color: #009CFF;" + 1052 | "-fx-background-radius: 18px;" + 1053 | "-fx-border-radius: 18px"); 1054 | 1055 | circleCloseIconOuter.setStyle("-fx-fill: white"); 1056 | circleCloseIconInner.setStyle("-fx-fill: #009CFF;" + 1057 | "-fx-stroke: #009CFF"); 1058 | 1059 | circleMinimizeIconOuter.setStyle("-fx-fill: white"); 1060 | circleMinimizeIconInner.setStyle("-fx-fill: #009CFF;" + 1061 | "-fx-stroke: #009CFF"); 1062 | 1063 | backBtnPane.setStyle("-fx-background-color: white;" + 1064 | "-fx-background-radius: 20px"); 1065 | exitBtnPane.setStyle("-fx-background-color: white;" + 1066 | "-fx-background-radius: 20px"); 1067 | minimizeBtnPane.setStyle("-fx-background-color: white;" + 1068 | "-fx-background-radius: 20px"); 1069 | 1070 | txtBack.setStyle("-fx-fill: #009CFF"); 1071 | txtClose.setStyle("-fx-fill: #009CFF"); 1072 | txtMinimize.setStyle("-fx-fill: #009CFF"); 1073 | 1074 | emojiPane.setVisible(false); 1075 | circleDarkTheme.setVisible(false); 1076 | circleLightTheme.setVisible(true); 1077 | } 1078 | 1079 | private void setDarkTheme() { 1080 | imgChatRoomBackground.setImage(new Image("assests/image/chatRoomBackgroundDark.png")); 1081 | imgPlayTechLogo.setImage(new Image("assests/image/playTechLogoChatRoomDark.png")); 1082 | imgDarkTheme.setImage(new Image("assests/icon/nightThemeIconSilver.png")); 1083 | imgLightTheme.setImage(new Image("assests/icon/lightThemeIconSilver.png")); 1084 | imgSendBtn.setImage(new Image("assests/icon/sendBtnIconSilver.png")); 1085 | imgEmojiIcon.setImage(new Image("assests/icon/emojiIcon.png")); 1086 | imgCloseIcon.setImage(new Image("assests/icon/closeIconSilver.png")); 1087 | imgMinimizeIcon.setImage(new Image("assests/icon/minimizeIconSilver.png")); 1088 | imgBackIcon.setImage(new Image("assests/icon/backBtnIconSilver.png")); 1089 | 1090 | // Apply styles directly to vertical scroll bar 1091 | scrollPane.lookup(".scroll-bar:vertical .thumb"). 1092 | setStyle("-fx-background-color: #A9A9A9; -fx-background-radius: 5em;"); 1093 | scrollPane.lookup(".scroll-bar:vertical .track"). 1094 | setStyle("-fx-background-color: #001F3F; -fx-border-color: #001F3F;"); 1095 | scrollPane.lookup(".increment-button"). 1096 | setStyle("-fx-background-color: #001F3F; -fx-border-color: #001F3F;"); 1097 | scrollPane.lookup(".decrement-button"). 1098 | setStyle("-fx-background-color: #001F3F; -fx-border-color: #001F3F;"); 1099 | 1100 | themeChangePane.setStyle("-fx-background-color: #A9A9A9;" + 1101 | "-fx-background-radius: 25px"); 1102 | 1103 | txtLogoChatRoom.setStyle("-fx-fill: #A9A9A9"); 1104 | lblUsername.setStyle("-fx-text-fill: #cbcbcb"); 1105 | circleOnlineIndicator.setStyle("-fx-fill: #001F3F;" + 1106 | "-fx-stroke: #cbcbcb;" + 1107 | "-fx-stroke-width: 3px"); 1108 | 1109 | vBox.setStyle("-fx-background-color: #001F3F"); 1110 | scrollPane.setStyle("-fx-background-color: #001F3F;" + 1111 | "-fx-control-inner-background: #001F3F;" + 1112 | "-fx-background: #001F3F;"); 1113 | 1114 | messageAreaPane.setStyle("-fx-background-color: #001F3F;" + 1115 | "-fx-background-radius: 16px"); 1116 | 1117 | txtMessage.setStyle("-fx-background-color: #001F3F;" + 1118 | "-fx-control-inner-background: #F0F0F0;" + 1119 | "-fx-background: #001F3F;" + 1120 | "-fx-text-fill: #F0F0F0;"); 1121 | 1122 | txtMessagePane.setStyle("-fx-background-color: #001F3F;" + 1123 | "-fx-background-radius: 25px"); 1124 | 1125 | sendBtnInnerPane.setStyle("-fx-background-color: #001F3F;" + 1126 | "-fx-background-radius: 25px"); 1127 | sendBtnOuterPane.setStyle("-fx-background-color: #A9A9A9;" + 1128 | "-fx-background-radius: 25px"); 1129 | 1130 | emojiPane.setStyle("-fx-background-color: #001F3F;" + 1131 | "-fx-border-color: #A9A9A9;" + 1132 | "-fx-background-radius: 18px;" + 1133 | "-fx-border-radius: 18px"); 1134 | 1135 | circleCloseIconOuter.setStyle("-fx-fill: #A9A9A9"); 1136 | circleCloseIconInner.setStyle("-fx-fill: #001F3F;" + 1137 | "-fx-stroke: #001F3F"); 1138 | 1139 | circleMinimizeIconOuter.setStyle("-fx-fill: #A9A9A9"); 1140 | circleMinimizeIconInner.setStyle("-fx-fill: #001F3F;" + 1141 | "-fx-stroke: #001F3F"); 1142 | 1143 | backBtnPane.setStyle("-fx-background-color: #CBCBCB;" + 1144 | "-fx-background-radius: 20px"); 1145 | exitBtnPane.setStyle("-fx-background-color: #CBCBCB;" + 1146 | "-fx-background-radius: 20px"); 1147 | minimizeBtnPane.setStyle("-fx-background-color: #CBCBCB;" + 1148 | "-fx-background-radius: 20px"); 1149 | 1150 | txtBack.setStyle("-fx-fill: #001F3F"); 1151 | txtClose.setStyle("-fx-fill: #001F3F"); 1152 | txtMinimize.setStyle("-fx-fill: #001F3F"); 1153 | 1154 | emojiPane.setVisible(false); 1155 | circleLightTheme.setVisible(false); 1156 | circleDarkTheme.setVisible(true); 1157 | } 1158 | 1159 | private void changeTheme() { 1160 | if (circleLightTheme.isVisible()) { 1161 | setDarkTheme(); 1162 | } else { 1163 | setLightTheme(); 1164 | } 1165 | } 1166 | 1167 | @FXML 1168 | void themeChangeBtnOnAction(ActionEvent event) { 1169 | changeTheme(); 1170 | } 1171 | } 1172 | --------------------------------------------------------------------------------