I am trying to create a JFrame
that displays a string in every even-numbered font size from 4 to 24. To do this I am trying to do a for loop that creates a drawString
that uses a Font
that increases in +2 font size everytime. Trying to get the next drawString
placed just underneath the previous by getting the getHeight()
of the previous and adding it to the varaible y
. However the JFrame
is empty when the program is run.
Where have I gone wrong?
import javax.swing.*;
import java.awt.*;
public class JFontSizeDemo extends JFrame {
int x = 10;
int y = 40;
int heightOfFont;
public void paint(Graphics g) {
super.paint(g);
for(int size = 4; size <= 24; size += 2) {
g.setFont(new Font("Arial", Font.BOLD, size));
g.drawString("Name", x, y);
heightOfFont = g.getFontMetrics().getHeight();
y += heightOfFont;
}
}
public static void main(String[] args) {
JFontSizeDemo frame = new JFontSizeDemo();
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Don't paint directly on JFrame
, which is a top level container. Use JComponent
or JPanel
. Override paintComponent()
for painting rather than paint()
.
Take a look at Performing Custom Painting tutorial for more details and examples.
Here is an slightly modified example of your code:
import javax.swing.*;
import java.awt.*;
public class FontSizeDemo {
private static void createAndShowUI() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = 0;
for(int size = 4; size <= 24; size += 2) {
g.setFont(new Font("Arial", Font.BOLD, size));
g.drawString("Name", 0, y);
int heightOfFont = g.getFontMetrics().getHeight();
y += heightOfFont;
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
};
frame.add(panel);
frame.setLocationByPlatform(true);
frame.setVisible(true);
frame.pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
Other than the introduction of JPanel
for painting, there is a quick tiny fix of y
coordinate, to ensure text remains in the same place after repaint. There is also SwingUtilities.invokeLater
. Also, usually there is no need to extend JFrame
at all.