If you ever wanted to see how easy it is to create a form using the JGoodies FormLayout
, this code shows a simple example:
/** * the "input panel" that goes in the North section of the Sarah3 mainframe BorderLayout. */ private def buildInputPanel: JPanel = { val layout = new FormLayout( // label textfield // ----- --------- "3px, 48px, 8px, pref:grow, 2dlu", //columns // ----- --------- "3dlu, p, 3dlu" //rows ) val builder = new PanelBuilder(layout) builder.setDefaultDialogBorder val cc = new CellConstraints builder.add(statusLabel, cc.xy(2,2)) builder.add(inputField, cc.xy(4,2)) builder.getPanel }
That code builds the JPanel
that’s shown at the top of this image, including the traffic light and wide textfield:
I describe more about how to use the JGoodies form layout PanelBuilder
in this tutorial, “Getting Java Swing components to grow and fill using JGoodies FormLayout.”
As one word of caution, this code is based on an old version of the JGoodies FormLayout
class. I haven’t learned their newer classes, and I don’t know if this will work with their latest releases.
The complete source code
If it helps to see that panel-building in the context of the complete class, here’s the source code for the current Sarah3 JFrame
:
package com.devdaily.sarah.gui import javax.swing._ import java.awt._ import com.jgoodies.forms.layout.FormLayout import com.jgoodies.forms.builder.PanelBuilder import com.jgoodies.forms.layout.CellConstraints trait StatusIndicator case object RedLight extends StatusIndicator case object YellowLight extends StatusIndicator case object GreenLight extends StatusIndicator case object NeutralLight extends StatusIndicator class MainFrame3 extends JFrame { import SwingUtils.invokeLater // status icon images val trafficLightRed = new ImageIcon(classOf[MainFrame3].getResource("trafficLightRedSmall.jpg")) val trafficLightYellow = new ImageIcon(classOf[MainFrame3].getResource("trafficLightYellowSmall.jpg")) val trafficLightGreen = new ImageIcon(classOf[MainFrame3].getResource("trafficLightGreenSmall.jpg")) val trafficLightNeutral = new ImageIcon(classOf[MainFrame3].getResource("trafficLightNeutralSmall.jpg")) setLayout(new BorderLayout) // input area val statusLabel = new JLabel val inputField = new JTextField statusLabel.setIcon(trafficLightNeutral) val inputPanel = buildInputPanel // output area val outputArea = new JEditorPane val scrollPane = new JScrollPane(outputArea) configureInputField configureOutputArea getContentPane.add(inputPanel, BorderLayout.NORTH) getContentPane.add(scrollPane, BorderLayout.CENTER) def setStatusIndicator(status: StatusIndicator): Unit = status match { case RedLight => invokeLater(statusLabel.setIcon(trafficLightRed)) case YellowLight => invokeLater(statusLabel.setIcon(trafficLightYellow)) case GreenLight => invokeLater(statusLabel.setIcon(trafficLightGreen)) case NeutralLight => invokeLater(statusLabel.setIcon(trafficLightNeutral)) } /** * the "input panel" that goes in the North section of the Sarah3 mainframe BorderLayout. */ private def buildInputPanel: JPanel = { val layout = new FormLayout( // label textfield // ----- --------- "3px, 48px, 8px, pref:grow, 2dlu", //columns // ----- --------- "3dlu, p, 3dlu" //rows ) val builder = new PanelBuilder(layout) builder.setDefaultDialogBorder val cc = new CellConstraints builder.add(statusLabel, cc.xy(2, 2)) builder.add(inputField, cc.xy(4, 2)) builder.getPanel } private def configureOutputArea { outputArea.setEditable(false) outputArea.setFont(inputField.getFont.deriveFont(20.0f)) outputArea.setBackground(new Color(230, 230, 230)) outputArea.setMargin(new Insets(20, 20, 20, 20)) outputArea.setText("Welcome to Sarah III") } private def configureInputField { inputField.setFont(inputField.getFont.deriveFont(24.0f)); inputField.setBorder(BorderFactory.createCompoundBorder(inputField.getBorder, BorderFactory.createEmptyBorder(5, 12, 5, 5))) inputField.setBounds(20, 20, inputField.getHeight, inputField.getWidth) inputField.setBackground(new Color(250, 250, 250)) } def setFocusInTextField { val mainFrame = this invokeLater(new Runnable { def run { mainFrame.requestFocusInWindow inputField.requestFocusInWindow Thread.sleep(500) } }) } }
I don’t have time to explain that code, but I hope it makes sense when you can see it along with the JFrame
image I shared above.