2017-01-19 9 views
0

Ich habe mein Bestes versucht, um eine JLabel Größe zu beheben, aber es ändert sich ständig und das verursacht andere Elemente in der GUI zu verschieben.Java Swing, wie JLabel Größe zu beheben

Ich habe sowohl die Größe und den Abstand der Komponenten angegeben. Laut GridBagLayout documentation, ipadx und ipady"Gibt die interne Auffüllung: wie viel hinzufügen auf die Größe der Komponente." Nach this Post, setMinimumSize und setMaximumSize können Sie die tatsächliche Größe der Komponente festlegen. Da ich sowohl die Größe als auch den Abstand festgelegt habe, wie ist es möglich, dass die Komponenten herumspringen, wenn Text in JLabel erscheint?

Ich konnte das in der Praxis lösen, indem ich einen Leerraum in den leeren Text fügte, aber das nervt mich immer wieder. Was versteh ich da nicht?

Hier ist ein SSCCE, der das Problem demonstriert. Es verfügt über Elemente, die in einem GridBagLayout angeordnet sind. Wenn Sie den Inhalt eines JLabels in einer Zelle ändern, werden alle Elemente verschoben.

import javax.swing.*; 
import java.awt.*; 
import java.io.*; 

public class F { 
public static void main(String[] args) throws IOException, InterruptedException { 
    JFrame frame = new JFrame(); 

    JPanel mainView = new JPanel(); 
    mainView.setPreferredSize(new Dimension(300, 300)); 
    mainView.setLayout(new GridBagLayout()); 

    JPanel contents = new JPanel(new GridBagLayout()); 
    GridBagConstraints gbc = new GridBagConstraints(); 
    gbc.insets = new Insets(1,3,3,3); 
    gbc.gridx = 0; 
    gbc.gridy = 0; 
    gbc.ipady = 2; 
    gbc.anchor = GridBagConstraints.EAST; 

    JLabel text1 = new JLabel("Some text: "); 
    contents.add(text1, gbc); 
    gbc.gridy++; 
    JLabel text2 = new JLabel("More text: "); 
    contents.add(text2, gbc); 
    gbc.gridy++; 
    JLabel text3 = new JLabel("Third line: "); 
    contents.add(text3, gbc); 
    gbc.gridx++; 
    gbc.gridy = 0; 

    JTextField textField1 = new JTextField(10); 
    contents.add(textField1, gbc); 
    gbc.gridx++; 
    gbc.gridy++; 
    gbc.gridx--; 

    JTextField textField2 = new JTextField(10); 
    contents.add(textField2, gbc); 
    gbc.gridy++; 

    JLabel sitePass = new JLabel(""); 
    sitePass.setMaximumSize(new Dimension(100, 15)); 
    sitePass.setMinimumSize(new Dimension(100, 15)); 
    //sitePass.setPreferredSize(new Dimension(100, 15)); // <-- this line fixes the problem 
    contents.add(sitePass, gbc); 

    mainView.add(contents); 

    frame.add(mainView); 
    frame.setSize(400, 400); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 

    while (true) { 
     Thread.sleep(1000); 
     sitePass.setText("Pushup time"); 
     Thread.sleep(1000); 
     sitePass.setText(""); 
    } 
} 
} 
+0

Wo ist dein [MCVE]? PS: 'setPreferedSize (int)' könnte helfen (ich setze die drei 'prefered, minimal, maximum' auf den gleichen Wert) um eine Größe zu fixieren – AxelH

+0

Sorry über das Beispiel, ich habe versehentlich zu viel gelöscht, als ich versuchte ein Minimum zu erstellen Beispiel. –

+0

Sie haben Recht, minimumSize und maximumSize war nicht genug. Hinzufügen preferredSize hat es behoben. –

Antwort

1

Schaukel die preferredSize für einige Layout. Durch die Einstellung wird das Etikett korrigiert.

Ich bin es gewohnt, ein JComponent auf fix, indem minimum, maximum und preferred Größe nur um sicher zu sein;)

PS: Ich werde versuchen, weitere Informationen hinzuzufügen, wie es zu benutzen.

+4

[Sollte ich die Verwendung der festgelegten (Preferred | Maximum | Minimum) Size-Methoden in Java Swing vermeiden? ] (http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumize-methods-in-java-swi) – MadProgrammer

+0

@MadProgrammer, danke dafür. Nun, es gibt Vor- und Nachteile in diesem Thread. Werde einen genaueren Blick auf jeden einzelnen werfen. Aber die akzeptierte Antwort schlägt vor, externe API (JGoodies) zu verwenden, um die Lücke im bereitgestellten Layout zu füllen ... – AxelH

+0

@MadProgrammer, hier können Sie eine drastische Verwendung dieser Eigenschaften in einem [demo] (http://docs.oracle .com/javase/tutorial/displayCode.html? code = http: //docs.oracle.com/javase/tutorial/uiswing/examples/components/HtmlDemoProject/src/components/HtmlDemo.java) von Oracle. – AxelH

3

Eine Möglichkeit, das Problem zu lösen. Wechsel:

JLabel sitePass = new JLabel(""); 

An:

JTextField sitePass = new JTextField("", 12); 
    sitePass.setOpaque(false); 
    sitePass.setBorder(null); 

Erläuterung: Ein JTextField hat eine Standardgröße durch die Anzahl der Spalten bestimmt, mit der Schriftart und Schriftgröße kombiniert. Die folgenden zwei Aussagen stellen sicher, dass es wie ein JLabel aussieht.

Eine Verbesserung wäre auch das Textfeld mit Akt wie ein Etikett zu machen, die von etwas entlang der Linien sein könnte:

sitePass.setEditable(false); 
    sitePass.setFocusable(false); 
1

Es gibt einen anderen Weg, um eine Dummy-Leerzeichen wie JComboBox zu verwenden.

//javax.swing.plaf.basic.BasicComboBoxUI#getDefaultSize() 
/** 
* Return the default size of an empty display area of the combo box using 
* the current renderer and font. 
* 
* @return the size of an empty display area 
* @see #getDisplaySize 
*/ 
protected Dimension getDefaultSize() { 
    // Calculates the height and width using the default text renderer 
    Dimension d = getSizeForComponent(getDefaultListCellRenderer() 
    .getListCellRendererComponent(listBox, " ", -1, false, false)); 
    return new Dimension(d.width, d.height); 
} 
import java.awt.*; 
import java.util.Objects; 
import javax.swing.*; 

public class DummyWhiteSpaceTest { 
    public JComponent makeUI(String dummy) { 
    JPanel mainView = new JPanel(new GridBagLayout()); 

    JPanel contents = new JPanel(new GridBagLayout()); 
    GridBagConstraints gbc = new GridBagConstraints(); 
    gbc.insets = new Insets(1, 3, 3, 3); 
    gbc.gridx = 0; 
    gbc.gridy = 0; 
    gbc.ipady = 2; 
    gbc.anchor = GridBagConstraints.EAST; 

    /* Text labels. */ 
    JLabel text1 = new JLabel("Some text: "); 
    contents.add(text1, gbc); 
    gbc.gridy++; 
    JLabel text2 = new JLabel("More text: "); 
    contents.add(text2, gbc); 
    gbc.gridy++; 
    JLabel text3 = new JLabel("Third line: "); 
    contents.add(text3, gbc); 
    gbc.gridx++; 
    gbc.gridy = 0; 

    JTextField textField1 = new JTextField(10); 
    contents.add(textField1, gbc); 
    gbc.gridx++; 
    gbc.gridy++; 
    gbc.gridx--; 

    JTextField textField2 = new JTextField(10); 
    contents.add(textField2, gbc); 
    gbc.gridy++; 

    //@see javax.swing.plaf.basic.BasicComboBoxUI#getDefaultSize() 
    //JLabel sitePass = new JLabel(" "); 
    JLabel sitePass = new JLabel(dummy); 
    sitePass.setFont(new Font("Monospaced", Font.PLAIN, 14)); 
    contents.add(sitePass, gbc); 

    mainView.add(contents); 

    (new Timer(1000, e -> { 
     if (Objects.equals(sitePass.getText(), dummy)) { 
     sitePass.setText("Pushup time"); 
     } else { 
     sitePass.setText(dummy); 
     } 
    })).start(); 

    return mainView; 
    } 
    public static void main(String... args) { 
    EventQueue.invokeLater(() -> { 
     DummyWhiteSpaceTest test = new DummyWhiteSpaceTest(); 
     JPanel p = new JPanel(new GridLayout(1, 2)); 
     p.add(test.makeUI("")); 
     p.add(test.makeUI(" ")); 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     f.getContentPane().add(p); 
     f.setSize(640, 240); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    }); 
    } 
}