Erhalten Höhe von mehrzeiliger Text mit fester Breite Dialog Resize zu machen richtig

StackOverflow https://stackoverflow.com/questions/1048224

  •  20-08-2019
  •  | 
  •  

Frage

Ich möchte einen Dialog schaffen, die eine Art von Textelement enthält (JLabel / JTextArea usw.), die mit mehreren ausgekleidet ist und die Worte wickeln. Ich möchte den Dialog einer festen Breite sein, aber die Höhe anpassen, je nachdem, wie groß der Text ist. Ich habe diesen Code:

import static javax.swing.GroupLayout.DEFAULT_SIZE;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TextSizeProblem extends JFrame {
  public TextSizeProblem() {

    String dummyString = "";
    for (int i = 0; i < 100; i++) {
      dummyString += " word" + i;  //Create a long text
    }
    JLabel text = new JLabel();
    text.setText("<html>" + dummyString + "</html>");

    JButton packMeButton = new JButton("pack");
    packMeButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        pack();
      }
    });

    GroupLayout layout = new GroupLayout(this.getContentPane());
    getContentPane().setLayout(layout);
    layout.setVerticalGroup(layout.createParallelGroup()
        .addComponent(packMeButton)
        .addComponent(text)
    );
    layout.setHorizontalGroup(layout.createSequentialGroup()
        .addComponent(packMeButton)
        .addComponent(text, DEFAULT_SIZE, 400, 400) //Lock the width to 400
    );

    pack();
  }

  public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JFrame frame = new TextSizeProblem();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }
}

Wenn das Programm läuft es wie folgt aussieht: alt text
(Quelle: lesc.se )

Aber ich würde den Dialog wie folgt aussehen mögen (wie wenn Sie das Pack-Taste drücken): alt text
(Quelle: lesc.se )

Ich vermute, dass das Problem ist, dass der Layout-Manager hatte nicht in der Lage, die richtige Höhe des Textes zu bestimmen, bevor es auf den Bildschirm angezeigt wird. Ich habe verschiedene Validate versucht (), ungültig (), validateTree () usw., aber haben keinen Erfolg haben.

War es hilfreich?

Lösung 3

fand ich eine Lösung für mein Problem. Durch das Ersetzen der JLabel mit einem JTextArea:

JTextArea text = new JTextArea();
text.setText(dummyString);
text.setLineWrap(true);
text.setWrapStyleWord(true);

Und Aufruf pack () durch einen Aufruf an den Layout-Manager folgte die Komponenten wieder durch eine andere Packung gefolgt Layout:

pack();
layout.invalidateLayout(this.getContentPane());
pack();

Dadurch wird der Layout-Manager auf die Breite anzupassen.

Der vollständige Code:

import static javax.swing.GroupLayout.DEFAULT_SIZE;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TextSizeProblem3 extends JFrame {
  public TextSizeProblem3() {

    String dummyString = "";
    for (int i = 0; i < 100; i++) {
      dummyString += " word" + i;  //Create a long text
    }
    JTextArea text = new JTextArea();
    text.setText(dummyString);
    text.setLineWrap(true);
    text.setWrapStyleWord(true);

    JButton packMeButton = new JButton("pack");
    packMeButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        pack();
      }
    });

    GroupLayout layout = new GroupLayout(this.getContentPane());
    getContentPane().setLayout(layout);
    layout.setVerticalGroup(layout.createParallelGroup()
        .addComponent(packMeButton)
        .addComponent(text)
    );
    layout.setHorizontalGroup(layout.createSequentialGroup()
        .addComponent(packMeButton)
        .addComponent(text, DEFAULT_SIZE, 400, 400) //Lock the width to 400
    );

    pack();
    layout.invalidateLayout(this.getContentPane());
    pack();
  }

  public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JFrame frame = new TextSizeProblem3();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }
}

(Sie können einige Anpassungen hinzufügen (Grenze, Farbe, etc.), so dass es sieht genauso aus wie die JLabel aber ich habe weggelassen dass)

Andere Tipps

Hier ist eine Anpassung des Codes, zu tun, was Sie wollen. Aber es braucht einen wenig Trick, um die Größe des Etiketts zu berechnen und deren bevorzugte Größe einstellen.

ich die Lösung hier

import static javax.swing.GroupLayout.DEFAULT_SIZE;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.text.View;

public class TextSizeProblem extends JFrame {
    public TextSizeProblem() {

        String dummyString = "";
        for (int i = 0; i < 100; i++) {
            dummyString += " word" + i; // Create a long text
        }
        JLabel text = new JLabel();
        text.setText("<html>" + dummyString + "</html>");

        Dimension prefSize = getPreferredSize(text.getText(), true, 400);

        JButton packMeButton = new JButton("pack");
        packMeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                pack();
            }
        });



        GroupLayout layout = new GroupLayout(this.getContentPane());
        getContentPane().setLayout(layout);
        layout.setVerticalGroup(layout.createParallelGroup().addComponent(packMeButton)
                .addComponent(text,DEFAULT_SIZE, prefSize.height, prefSize.height));
        layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(packMeButton)
                .addComponent(text, DEFAULT_SIZE, prefSize.width, prefSize.width) // Lock the width to 400
                );

        pack();
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new TextSizeProblem();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    private static final JLabel resizer = new JLabel();

    /**
     * Returns the preferred size to set a component at in order to render an html string. You can
     * specify the size of one dimension.
     */
    public static java.awt.Dimension getPreferredSize(String html, boolean width, int prefSize) {

        resizer.setText(html);

        View view = (View) resizer.getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey);

        view.setSize(width ? prefSize : 0, width ? 0 : prefSize);

        float w = view.getPreferredSpan(View.X_AXIS);
        float h = view.getPreferredSpan(View.Y_AXIS);

        return new java.awt.Dimension((int) Math.ceil(w), (int) Math.ceil(h));
    }
}

Ich denke, das ist, was Sie wollen:

JLabel label = new JLabel("<html><div style=\"width:200px;\">Lots of text here...</div></html>");
// add the label to some Container.

Dies wird die JLabel zu sein 200 Pixel breit beschränken und automatisch die Höhe anpassen, den Text passen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top