Originariamente inviata da
cersil
Ma se volessi sapere l'altezza del font di default?
Premessa: in java.awt.Component (dove ci sono le proprietà "base", es. font, foreground ecc..) i metodi getFont(), getForeground() e altri sono implementati concettualmente così: se il componente ha un proprio font/foreground/ecc... allora restituisce quello e basta. Altrimenti se non ce l'ha, lo chiede al parente "strutturale" (il contenitore, che a sua volta potrebbe chiederlo al proprio parente, ecc...).
Il tuo componente non ha un font predefinito, perché non ha un UI object (che per gli altri componenti JLabel, JButton ecc... viene dato dal Look&Feel impostato). Quindi il font arriva a chiederlo più in alto nella parentela strutturale.
Quando fai:
fMet fmt = new fMet();
il componente non ha ancora un parente strutturale.
Ma quando fai:
add(fmt);
il tuo componente diventa parte della struttura e quindi ha un parente. Ora, c'è sicuramente almeno un parente che ha un font predefinito. Il content-pane del JFrame è per default materialmente un JPanel, che ha di certo un font predefinito (dal L&F). Quindi dopo che hai aggiunto il tuo componente, esso "eredita" il font dal content-pane.
Detto questo, vedi questo esempio che ho scritto al volo. Definisce una "mia" label, che è proprio solo un "giocattolo" (ci vorrebbe ben altro per farla "bene") ma ti può dare l'idea:
codice:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FrameProvaMyLabel extends JFrame {
public FrameProvaMyLabel() {
super("Prova");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 400);
setLocationRelativeTo(null);
setLayout(new FlowLayout());
MyLabel label1 = new MyLabel("Prova");
label1.setBorder(BorderFactory.createLineBorder(Color.RED, 1));
add(label1);
MyLabel label2 = new MyLabel("abcdefghijklmnopqrstuvwxyz");
label2.setBorder(BorderFactory.createLineBorder(Color.MAGENTA, 5));
add(label2);
MyLabel label3 = new MyLabel("Ciao");
label3.setForeground(Color.RED);
label3.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 40));
label3.setBorder(BorderFactory.createMatteBorder(3, 8, 3, 8, Color.BLUE));
add(label3);
MyLabel label4 = new MyLabel("Hello");
label4.setPreferredSize(new Dimension(100, 40));
label4.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
add(label4);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FrameProvaMyLabel().setVisible(true);
}
});
}
}
class MyLabel extends JComponent {
private String label;
public MyLabel(String label) {
this.label = label;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Insets insets = getInsets(null);
FontMetrics fm = g.getFontMetrics();
int x = insets.left;
int y = insets.top + fm.getAscent();
g.drawString(label, x, y);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
Insets insets = getInsets(null);
FontMetrics fm = getFontMetrics(getFont());
int dx = insets.left + insets.right;
int dy = insets.top + insets.bottom;
int sw = fm.stringWidth(label);
int sh = fm.getHeight();
return new Dimension(sw+dx, sh+dy);
}
@Override
public Dimension getMinimumSize() {
if (isMinimumSizeSet()) {
return super.getMinimumSize();
}
return getPreferredSize();
}
@Override
public Dimension getMaximumSize() {
if (isMaximumSizeSet()) {
return super.getMaximumSize();
}
return getPreferredSize();
}
}
Ho usato un FlowLayout, che "rispetta" il preferred size dei componenti. Le prime 3 MyLabel hanno un preferred size calcolato. La quarta MyLabel ha un preferred size imposto esplicitamente.