Wie auto-adjust font size mehrere JLabel basierend auf container-Größe in eine glatte Art und Weise?
Ich brauche, um die Größe der schriftart für mehrere JLabel auf der Grundlage der Skalierungsfaktor verwendet, um die Größe der container. Um dies zu tun, ich bin Einstellung der schriftart für jede JLabel auf null, so dass Sie die Schrift des Containers. Es funktioniert, aber es produziert auch seltsame Ergebnisse.
Genau zu sein, scheint der text zu "lag" hinter den container, und manchmal wird es sogar abgeschnitten. Ich möchte dieses Verhalten zu vermeiden. Keine Ahnung, wie?
Beispiel-code die Simulation des Verhaltens:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.AffineTransform;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class TextResize implements Runnable {
public static void main(String[] args) {
TextResize example = new TextResize();
SwingUtilities.invokeLater(example);
}
public void run() {
JFrame frame = new JFrame("JLabel Text Resize");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(800, 400));
Container container = frame.getContentPane();
container.setLayout(new BorderLayout());
final JPanel labelContainer = new JPanel(new GridBagLayout());
labelContainer.setBorder(BorderFactory.createLineBorder(Color.black));
//initial font
final Font textFont = new Font("Lucida Console", Font.PLAIN, 10).deriveFont(AffineTransform.getScaleInstance(1, 1));
labelContainer.setFont(textFont);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0, 10, 0, 10);
c.weightx = 1;
for (int i = 0; i < 5; i++) {
JLabel f = new JLabel("Text here with possibly looooooooong words");
f.setBorder(BorderFactory.createLineBorder(Color.green));
f.setFont(null);//take the font from parent
c.gridy = i;
labelContainer.add(f, c);
}
JSlider slider = new JSlider(0,50000,10000);
slider.addChangeListener(new ChangeListener() {
double containerWidth = labelContainer.getPreferredSize().getWidth();
double containerHeight = labelContainer.getPreferredSize().getHeight();
@Override
public void stateChanged(ChangeEvent ev) {
JSlider source = (JSlider) ev.getSource();
double scale = (double) (source.getValue() / 10000d);
//scaling the container
labelContainer.setSize((int) (containerWidth * scale), (int) (containerHeight * scale));
//adjusting the font: why does it 'lag' ? why the truncation at times?
Font newFont = textFont.deriveFont(AffineTransform.getScaleInstance(scale, scale));
labelContainer.setFont(newFont);
//print (font.getSize() does not change?)
System.out.println(scale + " " + newFont.getTransform() + newFont.getSize2D());
}
});
container.add(slider, BorderLayout.NORTH);
JPanel test = new JPanel();
test.setLayout(null);
labelContainer.setBounds(5, 5, labelContainer.getPreferredSize().width, labelContainer.getPreferredSize().height);
test.add(labelContainer);
container.add(test, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
Bild:
http://i.stack.imgur.com/tZLOO.png
Dank,
-s
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie verwenden Sie eine der folgenden Methoden:
durch @trashgod
durch @StanislavL
durch @coobird
Ich habe irgendwie das problem gelöst hinzufügen:
Trotzdem danke.
Wenn die Leistung-Geschwindigkeit ein Problem ist, dann finden Sie vielleicht die folgenden Informationen über die 3 Methoden gezeigt, durch MKorbel oben nützlich.
Coobird code hat einige Einschränkungen, wenn Sie auf einem multi-call-basis (z.B. in einem sizeChanged-Hörer oder ein LayoutManager)
Trashgod Methode ist zwischen 2 und 4 mal langsamer als Stanislav ist (aber es ist auch entworfen, um die Fläche auszufüllen, die BEIDEN Richtungen der OP gefragt, die Frage also nicht unerwartet.)
Den code unten verbessert Stanislav ist die Rechteck-Methode (ausgehend von der aktuellen Schriftgröße jedes mal eher als Rückkehr zu MIN_FONT_SIZE jeder Zeit) und somit läuft zwischen 20 und 50 mal schneller als code, vor allem, wenn das Fenster/Schrift groß ist.
Es behebt auch eine Einschränkung darin, dass code, der nur effektiv arbeiten für labels liegt bei 0,0 (wie in dem Beispiel dort angegeben). Der code unten funktioniert für mehrere labels auf einem panel und an jedem Ort.