diff --git a/kotlin-app/src/main/kotlin/io/github/simonscholz/Main.kt b/kotlin-app/src/main/kotlin/io/github/simonscholz/Main.kt index ce5bc7d..17b1aeb 100644 --- a/kotlin-app/src/main/kotlin/io/github/simonscholz/Main.kt +++ b/kotlin-app/src/main/kotlin/io/github/simonscholz/Main.kt @@ -2,21 +2,14 @@ package io.github.simonscholz import io.github.simonscholz.model.QrCodeConfigViewModel import io.github.simonscholz.observables.SwingRealm -import io.github.simonscholz.qrcode.QrCodeConfig -import io.github.simonscholz.qrcode.QrCodeFactory -import io.github.simonscholz.qrcode.QrPositionalSquaresConfig +import io.github.simonscholz.service.RenderImageService.renderImage import io.github.simonscholz.ui.ImageUI import io.github.simonscholz.ui.MainUI import io.github.simonscholz.ui.PropertiesUI import org.eclipse.core.databinding.DataBindingContext -import java.awt.Component import java.awt.event.WindowAdapter import java.awt.event.WindowEvent -import java.awt.image.BufferedImage -import java.io.File -import javax.imageio.ImageIO import javax.swing.JFrame -import javax.swing.JOptionPane import javax.swing.SwingUtilities fun main() { @@ -39,6 +32,7 @@ fun main() { if (qrCodeConfigViewModel.qrCodeContent.value.isNotBlank()) { val qrCodeImage = renderImage(qrCodeConfigViewModel, frame) setImage(qrCodeImage) + imagePanel.revalidate() } } @@ -54,48 +48,10 @@ fun main() { if (qrCodeConfigViewModel.qrCodeContent.value.isNotBlank()) { val qrCodeImage = renderImage(qrCodeConfigViewModel, frame) setImage(qrCodeImage) + imagePanel.revalidate() } } } } } } - -private fun renderImage(qrCodeConfigViewModel: QrCodeConfigViewModel, component: Component): BufferedImage { - val builder = QrCodeConfig.Builder(qrCodeConfigViewModel.qrCodeContent.value) - .qrCodeSize(qrCodeConfigViewModel.size.value) - .qrCodeColorConfig( - bgColor = qrCodeConfigViewModel.backgroundColor.value, - fillColor = qrCodeConfigViewModel.foregroundColor.value, - ) - .qrBorderConfig( - color = qrCodeConfigViewModel.borderColor.value, - relativeSize = qrCodeConfigViewModel.relativeBorderSize.value, - relativeBorderRound = qrCodeConfigViewModel.borderRadius.value, - ) - .qrPositionalSquaresConfig( - qrPositionalSquaresConfig = QrPositionalSquaresConfig( - isCircleShaped = qrCodeConfigViewModel.positionalSquareIsCircleShaped.value, - relativeSquareBorderRound = qrCodeConfigViewModel.positionalSquareRelativeBorderRound.value, - centerColor = qrCodeConfigViewModel.positionalSquareCenterColor.value, - innerSquareColor = qrCodeConfigViewModel.positionalSquareInnerSquareColor.value, - outerSquareColor = qrCodeConfigViewModel.positionalSquareOuterSquareColor.value, - outerBorderColor = qrCodeConfigViewModel.positionalSquareOuterBorderColor.value, - ), - ) - if (qrCodeConfigViewModel.logo.value.isNotBlank() && File(qrCodeConfigViewModel.logo.value).exists()) { - runCatching { - ImageIO.read(File(qrCodeConfigViewModel.logo.value)).let { - builder.qrLogoConfig( - logo = it, - relativeSize = qrCodeConfigViewModel.logoRelativeSize.value, - bgColor = qrCodeConfigViewModel.logoBackgroundColor.value, - ) - } - }.onFailure { _ -> - JOptionPane.showMessageDialog(component, "You did not select a proper image", "Image Loading Error", JOptionPane.ERROR_MESSAGE) - } - } - val qrCodeConfig = builder.build() - return QrCodeFactory.createQrCodeApi().createQrCodeImage(qrCodeConfig) -} diff --git a/kotlin-app/src/main/kotlin/io/github/simonscholz/service/RenderImageService.kt b/kotlin-app/src/main/kotlin/io/github/simonscholz/service/RenderImageService.kt new file mode 100644 index 0000000..74794b8 --- /dev/null +++ b/kotlin-app/src/main/kotlin/io/github/simonscholz/service/RenderImageService.kt @@ -0,0 +1,71 @@ +package io.github.simonscholz.service + +import io.github.simonscholz.model.QrCodeConfigViewModel +import io.github.simonscholz.qrcode.QrCodeConfig +import io.github.simonscholz.qrcode.QrCodeFactory +import io.github.simonscholz.qrcode.QrPositionalSquaresConfig +import io.github.simonscholz.ui.ImageUI +import java.awt.Color +import java.awt.Component +import java.awt.image.BufferedImage +import java.io.File +import javax.imageio.ImageIO +import javax.swing.JOptionPane + +object RenderImageService { + fun renderImage(qrCodeConfigViewModel: QrCodeConfigViewModel, component: Component): BufferedImage { + val builder = QrCodeConfig.Builder(qrCodeConfigViewModel.qrCodeContent.value) + .qrCodeSize(qrCodeConfigViewModel.size.value) + .qrCodeColorConfig( + bgColor = qrCodeConfigViewModel.backgroundColor.value, + fillColor = qrCodeConfigViewModel.foregroundColor.value, + ) + .qrBorderConfig( + color = qrCodeConfigViewModel.borderColor.value, + relativeSize = qrCodeConfigViewModel.relativeBorderSize.value, + relativeBorderRound = qrCodeConfigViewModel.borderRadius.value, + ) + .qrPositionalSquaresConfig( + qrPositionalSquaresConfig = QrPositionalSquaresConfig( + isCircleShaped = qrCodeConfigViewModel.positionalSquareIsCircleShaped.value, + relativeSquareBorderRound = qrCodeConfigViewModel.positionalSquareRelativeBorderRound.value, + centerColor = qrCodeConfigViewModel.positionalSquareCenterColor.value, + innerSquareColor = qrCodeConfigViewModel.positionalSquareInnerSquareColor.value, + outerSquareColor = qrCodeConfigViewModel.positionalSquareOuterSquareColor.value, + outerBorderColor = qrCodeConfigViewModel.positionalSquareOuterBorderColor.value, + ), + ) + if (qrCodeConfigViewModel.logo.value.isNotBlank() && File(qrCodeConfigViewModel.logo.value).exists()) { + runCatching { + ImageIO.read(File(qrCodeConfigViewModel.logo.value)).let { + builder.qrLogoConfig( + logo = it, + relativeSize = qrCodeConfigViewModel.logoRelativeSize.value, + bgColor = qrCodeConfigViewModel.logoBackgroundColor.value, + ) + } + }.onFailure { _ -> + JOptionPane.showMessageDialog(component, "You did not select a proper image", "Image Loading Error", JOptionPane.ERROR_MESSAGE) + } + } + val qrCodeConfig = builder.build() + return QrCodeFactory.createQrCodeApi().createQrCodeImage(qrCodeConfig) + } + + fun renderInitialImage(): BufferedImage { + val resource = ImageUI::class.java.getClassLoader().getResource("avatar-60x.png") + val logo = ImageIO.read(resource) + val qrCodeConfig = QrCodeConfig.Builder("https://simonscholz.github.io/") + .qrBorderConfig(Color.BLACK) + .qrLogoConfig(logo) + .qrPositionalSquaresConfig( + QrPositionalSquaresConfig( + isCircleShaped = true, + relativeSquareBorderRound = .2, + centerColor = Color.RED, + ), + ) + .build() + return QrCodeFactory.createQrCodeApi().createQrCodeImage(qrCodeConfig) + } +} diff --git a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/CustomItems.kt b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/CustomItems.kt index 5ab414f..6e62d80 100644 --- a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/CustomItems.kt +++ b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/CustomItems.kt @@ -10,7 +10,7 @@ import javax.swing.JLabel import javax.swing.JPanel object CustomItems { - fun createColorPickerItem(propertiesPanel: JPanel, labelText: String, model: IObservableValue, dataBindingContext: DataBindingContext) { + fun createColorPickerItem(propertiesPanel: JPanel, labelText: String, model: IObservableValue, dataBindingContext: DataBindingContext, buttonLayoutConstraints: String = "wrap, growx") { propertiesPanel.add(JLabel(labelText)) val colorPicker = JButton("Choose Color").apply { isFocusPainted = false @@ -19,6 +19,6 @@ object CustomItems { model.value = JColorChooser.showDialog(propertiesPanel.parent, "Choose a color", Color.WHITE) } dataBindingContext.bindValue(colorPicker.toBackgroundColorObservable(), model) - propertiesPanel.add(colorPicker, "wrap, growx") + propertiesPanel.add(colorPicker, buttonLayoutConstraints) } } diff --git a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/ImageUI.kt b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/ImageUI.kt index 83f2256..3f9a412 100644 --- a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/ImageUI.kt +++ b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/ImageUI.kt @@ -1,29 +1,30 @@ package io.github.simonscholz.ui -import io.github.simonscholz.qrcode.QrCodeConfig -import io.github.simonscholz.qrcode.QrCodeFactory -import io.github.simonscholz.qrcode.QrPositionalSquaresConfig +import io.github.simonscholz.service.RenderImageService.renderInitialImage +import net.miginfocom.swing.MigLayout import java.awt.Color import java.awt.Dimension import java.awt.Graphics import java.awt.image.BufferedImage -import javax.imageio.ImageIO +import javax.swing.JLabel import javax.swing.JPanel object ImageUI { fun createImagePanel(): Pair Unit> { - val imageContainer = JPanel() + val imageContainer = JPanel(MigLayout("", "[center]")) imageContainer.background = Color.WHITE - val image = decentRedColor() + val image = renderInitialImage() val imageDrawPanel = ImagePanel().apply { setImage(image) } - imageContainer.add(imageDrawPanel) + imageContainer.add(imageDrawPanel, "wrap") val setImage = (imageDrawPanel::setImage as (BufferedImage) -> Unit) + imageContainer.add(JLabel("This image is just a preview of the actual qr code."), "wrap") + return Pair(imageContainer, setImage) } @@ -44,21 +45,4 @@ object ImageUI { } } } - - private fun decentRedColor(): BufferedImage { - val resource = ImageUI::class.java.getClassLoader().getResource("avatar-60x.png") - val logo = ImageIO.read(resource) - val qrCodeConfig = QrCodeConfig.Builder("https://simonscholz.github.io/") - .qrBorderConfig(Color.BLACK) - .qrLogoConfig(logo) - .qrPositionalSquaresConfig( - QrPositionalSquaresConfig( - isCircleShaped = true, - relativeSquareBorderRound = .2, - centerColor = Color.RED, - ), - ) - .build() - return QrCodeFactory.createQrCodeApi().createQrCodeImage(qrCodeConfig) - } } diff --git a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/MainUI.kt b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/MainUI.kt index 64505cf..30ee060 100644 --- a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/MainUI.kt +++ b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/MainUI.kt @@ -6,9 +6,9 @@ import javax.swing.JPanel object MainUI { fun createMainPanel(imagePanel: JPanel, propertiesPanel: JPanel): JPanel { - val mainPanel = JPanel(MigLayout()) - mainPanel.add(imagePanel, "grow") - mainPanel.add(propertiesPanel, "grow") + val mainPanel = JPanel(MigLayout("fill, wrap 2", "[70%][30%]")) + mainPanel.add(imagePanel, "grow, push, w 70%") + mainPanel.add(propertiesPanel, "grow, push, w 30%") return mainPanel } } diff --git a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/properties/LogoPropertiesUI.kt b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/properties/LogoPropertiesUI.kt index eba93ba..1c246c8 100644 --- a/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/properties/LogoPropertiesUI.kt +++ b/kotlin-app/src/main/kotlin/io/github/simonscholz/ui/properties/LogoPropertiesUI.kt @@ -55,7 +55,7 @@ object LogoPropertiesUI { logoPropertiesPanel.add(sizeSpinner, "wrap, growx, span 3, width 200:220:300") dataBindingContext.bindValue(sizeSpinner.toDoubleObservable(), qrCodeConfigViewModel.logoRelativeSize) - CustomItems.createColorPickerItem(logoPropertiesPanel, "Logo Background Color:", qrCodeConfigViewModel.logoBackgroundColor, dataBindingContext) + CustomItems.createColorPickerItem(logoPropertiesPanel, "Logo Background Color:", qrCodeConfigViewModel.logoBackgroundColor, dataBindingContext, "wrap, growx, span 2") return logoPropertiesPanel }