在 GridBagLayout 中自动调整组件大小
Automatically re-sizing a component within a GridBagLayout
在这段代码中,我在 GridBagLayout
中有一个面板,其中包含一个 JLabel
和一个 JTextField
。
import java.awt.*;
import javax.swing.*;
public class Simple
{
JFrame simpleWindow = new JFrame("Simple MCVE");
JPanel simplePanel = new JPanel();
JLabel lblSimple;
JTextField txtSimple;
public void numberConvertGUI()
{
simpleWindow.setBounds(10, 10, 420, 80);
simpleWindow.setMinimumSize(new Dimension(420, 80));
simpleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
simpleWindow.setLayout(new GridLayout(1,1));
createSimplePanel();
simpleWindow.getContentPane().add(simplePanel);
simpleWindow.setVisible(true);
}
public void createSimplePanel()
{
simplePanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
lblSimple = new JLabel();
c.weightx = 0.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0,2,0,2);
c.gridx = 0;
c.gridy = 0;
c.ipady = 0;
lblSimple.setText("Next to me is a JTextField: ");
lblSimple.setHorizontalAlignment(JLabel.RIGHT);
simplePanel.add(lblSimple, c);
txtSimple = new JTextField();
c.weightx = 0.5;
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 5;
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,2,0,2);
simplePanel.add(txtSimple, c);
}
public static void main(String[] args)
{
Simple s = new Simple();
s.numberConvertGUI();
}
}
我希望能够根据输入的数据量自动调整文本字段的大小。例如,当在 JTextField 中输入字符串 "How do I re-size this component automatically when the edge of it is reached?" 时,它看起来像这样。
然而,当我输入字符串时,我希望 JTextBox
和 JFrame
自动调整大小以生成看起来有点像这样的内容。
唯一的问题是我不知道有什么可以让我这样做的。如果您能帮助我完成这项任务,我将不胜感激。
编辑
当组件自动调整大小时,我还希望该组件有一个最大尺寸。这样,随着输入的数据越来越多,组件将不会不断调整某人计算机显示器的大小
Swing 中没有提供执行此操作的内置功能。
您需要做的是在文本字段后面的文档中添加一个 DocumentListener
,并在添加或删除文本时收到通知。
然后您需要计算您想要的文本字段的新大小(这本身可能很棘手 - 您可能需要使用 FontMetrics
)并重新调整控件大小以匹配。此时您可以轻松实现的最大尺寸,只需查看您要调整到的尺寸与您希望允许的最大尺寸相比即可。
有关 DocumentListener
的信息,请参阅此处:
https://docs.oracle.com/javase/tutorial/uiswing/events/documentlistener.html
有关 FontMetrics
的信息,请参阅此处:
https://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html
将我的布局更改为 MigLayout
后,我设法让我的代码执行我希望的操作。对于阅读本文并对如何操作感兴趣的任何人,请参阅下面的代码。
import java.awt.*;
import javax.swing.*;
import java.lang.Object.*;
import javax.swing.event.*;
import javax.swing.text.*;
import net.miginfocom.swing.MigLayout;
public class Simple
{
JFrame simpleWindow = new JFrame("Simple MCVE");
JPanel simplePanel = new JPanel();
JLabel lblTitle;
JLabel lblSimple;
JTextField txtSimple;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String []fontFamilies = ge.getAvailableFontFamilyNames();
int adv;
int widthOftxtSimple;
int i;
int xDimension;
public static int GetScreenWorkingWidth()
{
return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
}
int maxSize = GetScreenWorkingWidth()-50;
public void numberConvertGUI()
{
simpleWindow.setBounds(10, 10, 800, 100);
simpleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
simpleWindow.setResizable(false);
simpleWindow.setLayout(new GridLayout(1,1));
createSimplePanel();
simpleWindow.getContentPane().add(simplePanel);
simpleWindow.setVisible(true);
}
public void createSimplePanel()
{
MigLayout layout = new MigLayout("" , "[][grow]");
simplePanel.setLayout(layout);
lblTitle = new JLabel();
lblTitle.setText("This is a Title");
simplePanel.add(lblTitle, "wrap, align center,span 2");
lblSimple = new JLabel();
lblSimple.setText("Next to me is a JTextField: ");
simplePanel.add(lblSimple);
String sMPMConstraints = "width 615::"+maxSize;
txtSimple = new JTextField();
simplePanel.add(txtSimple, "grow, "+sMPMConstraints);
myDocumentListener();
}
public void myDocumentListener()
{
Document doc = txtSimple.getDocument();
DocumentListener listener = new DocumentListener()
{
@Override
public void insertUpdate(DocumentEvent e)
{
System.out.println("Insert");
String simpleString = txtSimple.getText();
Graphics graphics = txtSimple.getGraphics();
Font test = txtSimple.getFont();
FontMetrics metrics = graphics.getFontMetrics(test);
adv = metrics.stringWidth(simpleString);
System.out.println("The width of the string is: "+adv);
widthOftxtSimple = txtSimple.getWidth();
System.out.println("The width of the JTextField is: "+widthOftxtSimple);
if(xDimension<maxSize)
{
System.out.println("The x dimension is shorter than the max size which is: "+maxSize);
if(widthOftxtSimple-20<adv)
{
i = 615-20-adv; //615 in this case is the original length of the text box
//change for different text boxes
System.out.println("Value of i is: "+i);
xDimension = 800-i;
System.out.println("Value of xDimension is: "+xDimension);
simpleWindow.setBounds(10, 10, xDimension, 100);
}
}
else
{
System.out.println("The x dimension is longer than the max size which is: "+maxSize);
simpleWindow.setBounds(10, 10, maxSize, 100);
String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
int adv2 = metrics.stringWidth(lastCharSize);
xDimension = xDimension+adv2;
}
}
@Override
public void removeUpdate(DocumentEvent e)
{
System.out.println("Remove");
String simpleString = txtSimple.getText();
Graphics graphics = txtSimple.getGraphics();
Font test = txtSimple.getFont();
FontMetrics metrics = graphics.getFontMetrics(test);
widthOftxtSimple = txtSimple.getWidth();
System.out.println("The width of the JTextField is: "+widthOftxtSimple);
System.out.println("Value of xDimension is: "+xDimension);
if(xDimension<maxSize)
{
if(xDimension>800) //Original length of the JFrame
{
System.out.println("last char = " + simpleString.charAt(simpleString.length() - 1));
String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
int adv2 = metrics.stringWidth(lastCharSize);
int newX = xDimension-adv2;
simpleWindow.setBounds(10, 10, newX, 100);
xDimension = newX;
if(xDimension<800)
{
simpleWindow.setBounds(10, 10, 800, 100);
}
}
}
else
{
System.out.println("last char = " + simpleString.charAt(simpleString.length() - 1));
String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
int adv2 = metrics.stringWidth(lastCharSize);
int new3 = xDimension-adv2;
System.out.println("This is the else statement");
System.out.println("The new `xDimension` will be:"+ new3);
xDimension = new3;
}
}
@Override
public void changedUpdate(DocumentEvent e)
{
System.out.println("Change");
}
};
doc.addDocumentListener(listener);
}
public static void main(String[] args)
{
Simple s = new Simple();
s.numberConvertGUI();
}
}
要编译无误,您需要 MigLayout package 下载
在这段代码中,我在 GridBagLayout
中有一个面板,其中包含一个 JLabel
和一个 JTextField
。
import java.awt.*;
import javax.swing.*;
public class Simple
{
JFrame simpleWindow = new JFrame("Simple MCVE");
JPanel simplePanel = new JPanel();
JLabel lblSimple;
JTextField txtSimple;
public void numberConvertGUI()
{
simpleWindow.setBounds(10, 10, 420, 80);
simpleWindow.setMinimumSize(new Dimension(420, 80));
simpleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
simpleWindow.setLayout(new GridLayout(1,1));
createSimplePanel();
simpleWindow.getContentPane().add(simplePanel);
simpleWindow.setVisible(true);
}
public void createSimplePanel()
{
simplePanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
lblSimple = new JLabel();
c.weightx = 0.0;
c.weighty = 1.0;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(0,2,0,2);
c.gridx = 0;
c.gridy = 0;
c.ipady = 0;
lblSimple.setText("Next to me is a JTextField: ");
lblSimple.setHorizontalAlignment(JLabel.RIGHT);
simplePanel.add(lblSimple, c);
txtSimple = new JTextField();
c.weightx = 0.5;
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 5;
c.gridx = 1;
c.gridy = 0;
c.insets = new Insets(0,2,0,2);
simplePanel.add(txtSimple, c);
}
public static void main(String[] args)
{
Simple s = new Simple();
s.numberConvertGUI();
}
}
我希望能够根据输入的数据量自动调整文本字段的大小。例如,当在 JTextField 中输入字符串 "How do I re-size this component automatically when the edge of it is reached?" 时,它看起来像这样。
然而,当我输入字符串时,我希望 JTextBox
和 JFrame
自动调整大小以生成看起来有点像这样的内容。
唯一的问题是我不知道有什么可以让我这样做的。如果您能帮助我完成这项任务,我将不胜感激。
编辑
当组件自动调整大小时,我还希望该组件有一个最大尺寸。这样,随着输入的数据越来越多,组件将不会不断调整某人计算机显示器的大小
Swing 中没有提供执行此操作的内置功能。
您需要做的是在文本字段后面的文档中添加一个 DocumentListener
,并在添加或删除文本时收到通知。
然后您需要计算您想要的文本字段的新大小(这本身可能很棘手 - 您可能需要使用 FontMetrics
)并重新调整控件大小以匹配。此时您可以轻松实现的最大尺寸,只需查看您要调整到的尺寸与您希望允许的最大尺寸相比即可。
有关 DocumentListener
的信息,请参阅此处:
https://docs.oracle.com/javase/tutorial/uiswing/events/documentlistener.html
有关 FontMetrics
的信息,请参阅此处:
https://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html
将我的布局更改为 MigLayout
后,我设法让我的代码执行我希望的操作。对于阅读本文并对如何操作感兴趣的任何人,请参阅下面的代码。
import java.awt.*;
import javax.swing.*;
import java.lang.Object.*;
import javax.swing.event.*;
import javax.swing.text.*;
import net.miginfocom.swing.MigLayout;
public class Simple
{
JFrame simpleWindow = new JFrame("Simple MCVE");
JPanel simplePanel = new JPanel();
JLabel lblTitle;
JLabel lblSimple;
JTextField txtSimple;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String []fontFamilies = ge.getAvailableFontFamilyNames();
int adv;
int widthOftxtSimple;
int i;
int xDimension;
public static int GetScreenWorkingWidth()
{
return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
}
int maxSize = GetScreenWorkingWidth()-50;
public void numberConvertGUI()
{
simpleWindow.setBounds(10, 10, 800, 100);
simpleWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
simpleWindow.setResizable(false);
simpleWindow.setLayout(new GridLayout(1,1));
createSimplePanel();
simpleWindow.getContentPane().add(simplePanel);
simpleWindow.setVisible(true);
}
public void createSimplePanel()
{
MigLayout layout = new MigLayout("" , "[][grow]");
simplePanel.setLayout(layout);
lblTitle = new JLabel();
lblTitle.setText("This is a Title");
simplePanel.add(lblTitle, "wrap, align center,span 2");
lblSimple = new JLabel();
lblSimple.setText("Next to me is a JTextField: ");
simplePanel.add(lblSimple);
String sMPMConstraints = "width 615::"+maxSize;
txtSimple = new JTextField();
simplePanel.add(txtSimple, "grow, "+sMPMConstraints);
myDocumentListener();
}
public void myDocumentListener()
{
Document doc = txtSimple.getDocument();
DocumentListener listener = new DocumentListener()
{
@Override
public void insertUpdate(DocumentEvent e)
{
System.out.println("Insert");
String simpleString = txtSimple.getText();
Graphics graphics = txtSimple.getGraphics();
Font test = txtSimple.getFont();
FontMetrics metrics = graphics.getFontMetrics(test);
adv = metrics.stringWidth(simpleString);
System.out.println("The width of the string is: "+adv);
widthOftxtSimple = txtSimple.getWidth();
System.out.println("The width of the JTextField is: "+widthOftxtSimple);
if(xDimension<maxSize)
{
System.out.println("The x dimension is shorter than the max size which is: "+maxSize);
if(widthOftxtSimple-20<adv)
{
i = 615-20-adv; //615 in this case is the original length of the text box
//change for different text boxes
System.out.println("Value of i is: "+i);
xDimension = 800-i;
System.out.println("Value of xDimension is: "+xDimension);
simpleWindow.setBounds(10, 10, xDimension, 100);
}
}
else
{
System.out.println("The x dimension is longer than the max size which is: "+maxSize);
simpleWindow.setBounds(10, 10, maxSize, 100);
String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
int adv2 = metrics.stringWidth(lastCharSize);
xDimension = xDimension+adv2;
}
}
@Override
public void removeUpdate(DocumentEvent e)
{
System.out.println("Remove");
String simpleString = txtSimple.getText();
Graphics graphics = txtSimple.getGraphics();
Font test = txtSimple.getFont();
FontMetrics metrics = graphics.getFontMetrics(test);
widthOftxtSimple = txtSimple.getWidth();
System.out.println("The width of the JTextField is: "+widthOftxtSimple);
System.out.println("Value of xDimension is: "+xDimension);
if(xDimension<maxSize)
{
if(xDimension>800) //Original length of the JFrame
{
System.out.println("last char = " + simpleString.charAt(simpleString.length() - 1));
String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
int adv2 = metrics.stringWidth(lastCharSize);
int newX = xDimension-adv2;
simpleWindow.setBounds(10, 10, newX, 100);
xDimension = newX;
if(xDimension<800)
{
simpleWindow.setBounds(10, 10, 800, 100);
}
}
}
else
{
System.out.println("last char = " + simpleString.charAt(simpleString.length() - 1));
String lastCharSize = simpleString.charAt(simpleString.length() - 1)+"";
int adv2 = metrics.stringWidth(lastCharSize);
int new3 = xDimension-adv2;
System.out.println("This is the else statement");
System.out.println("The new `xDimension` will be:"+ new3);
xDimension = new3;
}
}
@Override
public void changedUpdate(DocumentEvent e)
{
System.out.println("Change");
}
};
doc.addDocumentListener(listener);
}
public static void main(String[] args)
{
Simple s = new Simple();
s.numberConvertGUI();
}
}
要编译无误,您需要 MigLayout package 下载