Java swing glue component (Filler) adds a useless 1 pixel space at the end of the panel

76 Views Asked by At

I'm trying to create swing program with custom titlebar (undecorated window). I create a JPanel with BoxLayout, add some components, including glue between title label and buttons (minimize and exit). TitleBarPanel class:

package ru.robert_grammy.gifshooter.component.ui

import ru.robert_grammy.gifshooter.ResourceLoader
import ru.robert_grammy.gifshooter.component.listener.FrameMouseDraggedListener
import ru.robert_grammy.gifshooter.engine.ProgramStrings
import ru.robert_grammy.gifshooter.component.engine.ProgramButton
import ru.robert_grammy.gifshooter.engine.UiSettings
import java.awt.Dimension
import javax.swing.*
import kotlin.system.exitProcess

class TitleBarPanel(private val frame: JFrame) : JPanel() {

    companion object {
        private const val TITLE_ICON_FILENAME = "icon.png"
        private const val MINIMIZE_BUTTON_ICON_FILENAME = "minimize.png"
        private const val CLOSE_BUTTON_ICON_FILENAME = "close.png"
    }

    val titleLabel = JLabel().let {
        it.foreground = UiSettings.Colors.DEFAULT_TEXT_COLOR.get()
        it.font = UiSettings.Fonts.DEFAULT_FONT.get()
        it.text = ProgramStrings.PROGRAM_TITLE.get()
        it.icon = ResourceLoader.getIcon(TITLE_ICON_FILENAME)
        it.preferredSize = Dimension(UiSettings.Sizes.DEFAULT_LINE_LABEL.getWidth(), UiSettings.Sizes.DEFAULT_LINE_LABEL.getHeight())
        add(it)
        add(Box.createGlue())
    }

    val minimizeButton = ProgramButton().let {
        it.backgroundColor = UiSettings.Colors.BUTTON_COLOR.get()
        it.hoverColor = UiSettings.Colors.DEFAULT_HOVER_BUTTON_COLOR.get()
        it.pressColor = UiSettings.Colors.DEFAULT_PRESS_BUTTON_COLOR.get()

        it.isBorderPainted = false
        it.isFocusable = false

        it.preferredSize = Dimension(UiSettings.Sizes.TITLE_BUTTON.getWidth(), UiSettings.Sizes.TITLE_BUTTON.getHeight())
        it.icon = ResourceLoader.getIcon(MINIMIZE_BUTTON_ICON_FILENAME)
        it.addActionListener {
            frame.extendedState = JFrame.ICONIFIED
        }
        add(it)
    }
    val closeButton = ProgramButton().let {
        it.backgroundColor = UiSettings.Colors.BUTTON_COLOR.get()
        it.hoverColor = UiSettings.Colors.EXIT_HOVER_BUTTON_COLOR.get()
        it.pressColor = UiSettings.Colors.EXIT_PRESS_BUTTON_COLOR.get()

        it.isBorderPainted = false
        it.isFocusable = false

        it.preferredSize = Dimension(UiSettings.Sizes.TITLE_BUTTON.getWidth(), UiSettings.Sizes.TITLE_BUTTON.getHeight())
        it.icon = ResourceLoader.getIcon(CLOSE_BUTTON_ICON_FILENAME)
        it.addActionListener {
            exitProcess(0)
        }
        add(it)
    }

    private val frameMouseDraggedListener = FrameMouseDraggedListener(frame)

    init {
        layout = BoxLayout(this, BoxLayout.LINE_AXIS)
        background = UiSettings.Colors.PRIMARY_COLOR.get()
        foreground = UiSettings.Colors.DEFAULT_TEXT_COLOR.get()
        addMouseMotionListener(frameMouseDraggedListener)
    }

}

I added instance to frame's content pane after. And it works correctly. Titlebar

But if I add something large to the main panel, Filler stretches as expected, but a one pixel wide space appears at the end of the panel. Extra pixel space

And if I add more Fillers, the space gets bigger. More Fillers = larger empty space

I realize that the Filler should be alone, just demonstrating that the empty space appears because of it. That 1 pixel of emptiness really stresses me out, as the button was supposed to be tight against the end of the pane.

I tried using Filler with a given unchanging width. It helped to get rid of the empty space, but the window lost its flexibility.

I assume that a working alternative is BorderLayout/FlowLayout. Label on one side, a panel with buttons on the other and everything should work. I suppose that's the way I'll go, but before I do I'm still wondering if there's any way to fix the extra space when adding a Glue component.

0

There are 0 best solutions below