Swing/AWT
Swing and AWT are libraries bundled with Java to create graphical interfaces. Swing was introduced as a replacement for AWT, but it didn't completely replace AWT.
β οΈ Modern developers prefer to use JavaFX, which heavily cuts down the quantity of code, and the time invested for the same output.
These are the two base packages:
import java.awt.*; // awt
import javax.swing.*; // swing
π Swing classes usually start with J
followed by their AWT name.
Components
A component is a graphical entity such as a Button.
All Swing components are extending JComponent
while AWT components are extending Component
.
JComponent aComponent = new JButton();
Child components
aComponent.add(anotherOne);
aComponent.remove(anotherOne);
aComponent.removeAll();
Drawing
aComponent.repaint(); // redraw if modified
aComponent.revalidate(); // force redraw
aComponent.setVisible(true); // show
Style
aComponent.setFont(new Font("name", Font.PLAIN, 20));
aComponent.setOpaque(true); // mark as having a background
aComponent.setBackground(Color.RED); // background color if opaque
aComponent.setForeground(Color.WHITE); // text color
Size
// DO NOT USE setSize, it's ignored by most layouts
aComponent.setPreferredSize(new Dimension(50,50));
// MAY BE IGNORED by the layout
aComponent.setSize(new Dimension(50,50));
aComponent.setMinimumSize(new Dimension(50,50));
aComponent.setMaximumSize(new Dimension(50,50));
Examples of components
JFrame - window
You'll usually create a frame, and add a component inside. Then, you'll make it visible.
JFrame f = new JFrame("title");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when "x" pressed
f.setSize(500,500); // size
f.setLocation(0,0); // location in the screen
f.add(component); // add ONE component, usually a JPanel
f.setVisible(true); // show, false by default
JLabel - a text
JLabel label = new JLabel("text");
label.setHorizontalAlignment(JLabel.CENTER);
label.setText("xxxx");
String text = label.getText();
JButton - a button
JButton b = new JButton("test");
b.addActionListener( /* refer to listeners */ );
Input fields
-
JTextArea
: a text input zone -
JTextField
: a text input field -
JPassword
: a password input field -
JCheckBox
: a checkbox input field -
JRadioButton
: a radio button -
JList
: a select list
JPanel - group elements
We usually put components in a JPanel, allowing us to perform an action (move, show/hide) on the whole group.
JPanel p = new JPanel();
p.add(xxx); // add "xxx" to the group
π See also: JScrollPane
for a scrollable panel.
Layout managers
Layout Managers determine how child components are displayed. They are commonly used with JPanel
πΌοΈ.
// some constructors can take a layout manager too
aComponent.setLayout(LayoutManager);
By default, the layout manager is a FlowLayout.
FlowLayout
In the FlowLayout, each component takes its preferred size. Elements could be aligned to the left, to the right, or to the center (default).
aComponent.setLayout(new FlowLayout(FlowLayout.LEFT));
BorderLayout
The BorderLayout divides the container into 5 areas. The center takes up the remaining space. North and South expand as much as possible horizontally. East and West expand as much as possible vertically.
aComponent.setLayout(new BorderLayout());
aComponent.add(component1, BorderLayout.NORTH);
aComponent.add(component2, BorderLayout.SOUTH);
aComponent.add(component3, BorderLayout.CENTER); // default
aComponent.add(component4, BorderLayout.EAST);
aComponent.add(component5, BorderLayout.WEST);
GridBagLayout
GridBagLayout is the most versatile layout. Before adding a component, you'll define the constraint on it (position...).
aComponent.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0; c.gridy = 0; // position
c.gridwidth = 1; c.gridheight = 1; // colspan/rowspan
c.weightx = 0; c.weighty = 0; // expand priority
c.anchor = GridBagConstraints.LINE_START; // alignement
c.fill = GridBagConstraints.HORIZONTAL; // expand behavior
c.insets = new Inset(top, left, bottom, right); // padding
aComponent.add(someComponent, c);
GridLayout
In a GridLayout, all rows/columns have the same width/height.
aComponent.setLayout(new GridLayout(rowCount, colCount));
CardLayout
In a CardLayout, we can swap the content displayed with another view.
CardLayout cardLayout = new CardLayout();
aComponent.setLayout(cardLayout);
aComponent.add("key", view); // adding a view
cardLayout.show(aComponent, "key"); // select a view
cardLayout.first(aComponent); // show the first view
cardLayout.next(aComponent); // show the next view
cardLayout.previous(aComponent); // show the previous view
Event listeners
Listeners allow us to react when the user interacts with the view, such as by clicking on a button.
aComponent.addMouseListener(/* a listener here */);
aComponent.removeMouseListener(/* a listener here */);
aButton.addActionListener(/* a listener here */);
aJFrame.addWindowListener(/* a listener here */);
// see also: MouseMotionListener, MouseWheelListener...
Mouse listener
You can also use MouseAdapter
(abstract class) implementing MouseListener, MouseWheelListener, and MouseMotionListener.
public class MyMouseListener implements MouseListener {
@Override // click
public void mouseClicked(MouseEvent e){}
@Override // hover (entering)
public void mouseEntered(MouseEvent e){}
@Override // hover (exiting)
public void mouseExited(MouseEvent e){}
@Override
public void mousePressed(MouseEvent e){}
@Override
public void mouseReleased(MouseEvent e){}
}
Action listener
This listener is called when a button is pressed.
// public class MyActionListener implements ActionListener
// public void actionPerformed(ActionEvent e)
aButton.addActionListener(e -> {
// get the button (if needed)
Object source = e.getSource();
JButton button = (JButton) source;
// get the text of the button (if needed)
String text = e.getActionCommand();
// ...
});
Window listener
You can also use WindowAdapter
(abstract class) implementing WindowListener, WindowStateListener, and WindowFocusListener
public class MyWindowListener implements WindowListener {
@Override // never called?
public void windowClosed(WindowEvent e){}
@Override // before closing
public void windowClosing(WindowEvent e){}
@Override
public void windowActivated(WindowEvent e){}
@Override
public void windowDeactivated(WindowEvent e){}
@Override
public void windowIconified(WindowEvent e){}
@Override
public void windowDeiconified(WindowEvent e){}
@Override // never called?
public void windowOpened(WindowEvent e){}
}
Drawing
You can draw your own component by extending JComponent
and overriding paintComponent
.
import javax.swing.JComponent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.RenderingHints;
public class Demo extends JComponent {
@Override
protected void paintComponent(Graphics g) {
// make a copy just in case
Graphics2D copy = (Graphics2D) g.create();
// do not draw a background if not opaque
if (isOpaque()) {
copy.setColor(getBackground());
copy.fillRect(0, 0, getWidth(), getHeight());
}
// ...
}
}
Some parts of code you might use:
// drawing options
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
copy.setRenderingHints(rh);
// color, font, ...
copy.setColor(Color.RED);
copy.setFont(new Font("name", Font.PLAIN, 20));
// forms
copy.drawLine(int x1, int y1, int x2, int y2);
copy.drawPolygon( int[] xPoints, int[] yPoints, int nPoints);
copy.drawRect(int x, int y, int width, int height);
// ...
// images
// (Toolkit.getDefaultToolkit().getImage(path) ???)
copy.drawImage(Image img, int x, int y, ImageObserver observer)
π» To-do π»
Stuff that I found, but never read/used yet.
- Event thread
-
SwingUtilities.invokeLater(Runnable);
-
JOptionPane
,JFileChooser