Creating Interactive Interfaces with Core Swing Components
Swing's component library provides versatile building blocks for desktop applications. This guide walks through several frequently used components, illustrating how to handle styled text, file operations, formatted input, frames, and more through practical code snippets.
Working with Styled Text: Editor Pane and Text Pane
JEditorPane and its subclass JTextPane support rich text. An editor pane can render plain text, HTML, or RTF; a text pane adds styled document capabilities.
To load HTML from a resource and display it non-editable:
JEditorPane helpViewer = new JEditorPane();
helpViewer.setEditable(false);
URL helpResource = getClass().getResource("/docs/help.html");
if (helpResource != null) {
try {
helpViewer.setPage(helpResource);
} catch (IOException ex) {
ex.printStackTrace();
}
}
JScrollPane scroller = new JScrollPane(helpViewer);
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroller.setPreferredSize(new Dimension(300, 200));
When the content type changes (for example from plain text to HTML), the underlying document and editor kit are swapped automatically. Keep this in mind if you have registered document listeners.
JTextPane requires a StyledDocument. By default it uses DefaultStyledDocument. To populate a text pane with styled text:
JTextPane textPane = new JTextPane();
StyledDocument styledDoc = textPane.getStyledDocument();
// Define some named styles
Style heading = styledDoc.addStyle("heading", null);
StyleConstants.setFontSize(heading, 18);
StyleConstants.setBold(heading, true);
Style normal = styledDoc.addStyle("normal", null);
StyleConstants.setFontSize(normal, 12);
try {
styledDoc.insertString(styledDoc.getLength(), "Welcome\n", heading);
styledDoc.insertString(styledDoc.getLength(), "This is a sample paragraph.", normal);
} catch (BadLocationException ble) {
ble.printStackTrace();
}
Embedding images and components is06 possible through the styled document API, while in JEditorPane you can achieve this via HTML <img> tags.
Selecting Files with JFileChooser
A file chooser dialog lets users browse and select files or directories. The Standard open dialog is shown with:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File("/home/user"));
int result = fileChooser.showOpenDialog(parentComponent);
if (result == JFileChooser.APPROVE_OPTION) {
File selected = fileChooser.getSelectedFile();
// open or process the file
}
lamasFor a save dialog, call showSaveDialog. The chooser remembers the last directory between invocations when you reuse the same instance.
To restrict the visible files, implement a FileFilter and add it to the list of choosable filters:
fileChooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
if (f.isDirectory()) return true;
String name = f.getName().toLowerCase();
return name.endsWith(".pdf") || name.endsWith(".docx");
}
public String getDescription() {
return "Documents (*.pdf, *.docx)";
}
});
fileChooser.setAcceptAllFileFilterUsed(false);
acciCustomise the file view (icons and type descriptions) by supplying a FileView. An accessory component can preview images or provide extra controls; attach it with setAccessory and listen for property changes like SELECTED_FILE_CHANGED_PROPERTY.
Formatted Input using JFormattedTextField
A JFormattedTextField links a text field with a formatter. The formatter translates between a typed value and its textual reprseentation. Using a NumberFormat:
NumberFormat currencyFmt = NumberFormat.getCurrencyInstance();
JFormattedTextField priceField = new JFormattedTextField(currencyFmt);
priceField.setValue(19.99);
priceField.setColumns(8);
priceField.addPropertyChangeListener("value", evt -> updateTotal());
For fixed patterns (e.g. phone numbers), MaskFormatter is convenient:
MaskFormatter phoneMask = new MaskFormatter("(##) #####-####");
phoneMask.setPlaceholderCharacter('_');
JFormattedTextField phoneEntry = new JFormattedTextField(phoneMask);
To define different formatters for editing and display states, use a DefaultFormatterFactory:
DefaultFormatterFactory factory = new DefaultFormatterFactory(
new NumberFormatter(displayFormat),
new NumberFormatter(displayFormat),
new NumberFormatter(editFormat)
);
JFormattedTextField field = new JFormattedTextField(factory);
The value is committed automatically on focus loss or Enter key; you can also call commitEdit().
Building Application Windows with JFrame
A JFrame is a top-level container with a title bar and borders. The basic setup:
JFrame mainWindow = new JFrame("My App");
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.getContentPane().add(new JLabel("Hello"), BorderLayout.CENTER);
mainWindow.pack();
mainWindow.setLocationRelativeTo(null);
mainWindow.setVisible(true);
acciThedecoration type can be switched to the look and feel using:
JFrame.setDefaultLookAndFeelDecorated(true);
before creating the frame.alenYou can also supply a custom icon via setIconImage. To completely remove decorations, call setUndecorated(true) before packing.
Acciones closing behaviour is controlled by setDefaultCloseOperation: EXIT_ON_CLOSE, DISPOSE_ON_CLOSE, HIDE_ON_CLOSE, or DO_NOTHING_ON_CLOSE combined with a WindowListener.
Internal Windows with JInternalFrame
Internal frames live inside a JDesktopPane, allowing a multiple-document interface. Each internal frame is managed like a regular frame.
JDesktopPane desktop = new JDesktopPane();
mainFrame.setContentPane(desktop);
JInternalFrame docFrame = new JInternalFrame("Document 1", true, true, true, true);
docFrame.getContentPane().add(new JTextArea());
docFrame.pack();
docFrame.setVisible(true);
desktop.add(docFrame);
try { docFrame.setSelected(true); } catch (PropertyVetoException ignored) {}
Each internal frame must be sized and made visible explicitly. Use moveToFront/moveToBack to alter Z order. Performance can be improved by switching to outline dragging:
desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
Labels, Layered Panes, and Lists
JLabel displays unselectable text and images. Alignment and icon-text gaps are configurable:
JLabel infoLabel = new JLabel("Copy", icon, JLabel.CENTER);
infoLabel.setHorizontalTextPosition(JLabel.CENTER);
infoLabel.setVerticalTextPosition(JLabel.BOTTOM);
infoLabel.setIconTextGap(10);
To associate a label with another component for accessibility, call infoLabel.setLabelFor(inputField).
JLayeredPane arranges components in layers (depths). Higher integers are painted on top.
JLayeredPane layers = new JLayeredPane();
layers.setPreferredSize(new Dimension(400, 300));
JLabel back = new JLabel("Background", JLabel.CENTER);
back.setBounds(50, 50, 200, 100);
layers.add(back, Integer.valueOf(0));
JLabel front = new JLabel("Foreground", JLabel.CENTER);
front.setBounds(70, 70, 200, 100);
layers.add(front, Integer.valueOf(1));
layers.moveToFront(front); // bring to top within its layer
JList presents a scrollable selection list. Using DefaultListModel makes items mutable:
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement("Red");
model.addElement("Green");
model.addElement("Blue");
JList<String> colorList = new JList<>(model);
colorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
colorList.setLayoutOrientation(JList.VERTICAL);
colorList.setVisibleRowCount(5);
JScrollPane listScroller = new JScrollPane(colorList);
Respond to selection changes with a ListSelectionListener and update model elements with addElement / remove methods. Custom renderers let you display items as complex components by implementing ListCellRenderer.
These core Swing components cover a wide range of UI needs. Each can be extended and themed with the pluggable look and feel to build polished desktop applications.