【发布时间】:2015-01-25 13:20:15
【问题描述】:
我是 Java 新手,我一直在尝试构建一个简单的即时消息程序。我希望文本框(您在发送消息之前键入消息的地方)在一个人输入大消息时动态更改大小(带最大高度限制),有点像 WhatsApp 或 iMessage 上发生的情况。
我尝试计算文本框中的文本行数(考虑到文本换行的影响),然后根据文本换行的行数增加/减少文本框的高度展示。我使用 getScrollableUnitIncrement() 方法确定了 1 行文本的高度。
另外,据我所知,有没有比我上面概述的更好的方法来动态更改文本框的大小?
我使用了嵌入在 JScrollPane 中的 JTextArea,并在 JTextArea 上使用了 componentListener 来适当地调整文本框的大小。
请检查组件侦听器方法中的 while 循环,因为我认为这部分程序无法正常工作...
这是代码的sn-p:
public class clienterrors extends JFrame {
private JTextArea userText;
private JTextPane chatWindow;
private String userName="testName";
private Document doc;
// Automatic resizing of the text box
private static Dimension textBoxSize = new Dimension(20, 20);
public static int numRows = 1;
private static final int rowHeight = 20;
private final int maxHeight = 80;
public static void main(String[] args) {
clienterrors george = new clienterrors();
george.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public clienterrors(){
super("Client instant messaging platform");
// Chat window initialisation
chatWindow = new JTextPane();
chatWindow.setEditable(false);
doc = chatWindow.getDocument();
add(new JScrollPane(chatWindow), BorderLayout.CENTER);
// Text box initialisation
userText = new JTextArea();
userText.setLineWrap(true);
userText.setWrapStyleWord(true);
JScrollPane jsp = new JScrollPane(userText);
jsp.setPreferredSize(textBoxSize);
jsp.setMaximumSize(new Dimension(20, 40));
// Gets the text box to resize as appropriate
userText.addComponentListener(
new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
// Needs to cater for when removing & pasting large messages into the text box
while (countLines(userText) > numRows && textBoxSize.getHeight() < maxHeight) {
textBoxSize.setSize(20, (int) textBoxSize.getHeight() + rowHeight);
revalidate();
numRows++; // numRows is used as an update to see which
}
while (countLines(userText) < numRows && textBoxSize.getHeight() > 20){
textBoxSize.setSize(20, (int)textBoxSize.getHeight() - rowHeight);
revalidate();
numRows--;
}
}
}
);
// Allows u to send text from text box to chat window
userText.addKeyListener(
new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyChar() == '\n' && enterChecker(userText.getText())){
// returns the text (-1 on the substring to remove the \n escape character when pressing enter)
showMessage("\n" + userName + ": " + userText.getText().substring(0, userText.getText().length() - 1));
userText.setText("");
}
}
}
);
add(jsp, BorderLayout.SOUTH);
//JFrame properties
setSize(300, 400);
setVisible(true);
}
// shows message on the chat window
private void showMessage(final String text){
SwingUtilities.invokeLater(
new Runnable() {
@Override
public void run() {
try{
doc.insertString(doc.getLength(), text, null);
}catch(BadLocationException badLocationException){
badLocationException.printStackTrace();
}
// place caret at the end (with no selection), so the newest message can be automatically seen by the user
chatWindow.setCaretPosition(chatWindow.getDocument().getLength());
}
}
);
}
// Prevents the user from sending empty messages that only contain whitespace or \n
private static boolean enterChecker(String t){
for(int i=0; i<t.length(); i++)
if (t.charAt(i) != '\n' && t.charAt(i) != ' ')
return true;
return false;
}
// This counts the number of wrapped lines in the text box to compare to numRows - only used to resize the text box
// (got this off the internet)
private static int countLines(JTextArea textArea) {
if(!enterChecker(textArea.getText())) return 0; // this prevents getting an error when you're sending an empty message
AttributedString text = new AttributedString(textArea.getText());
FontRenderContext frc = textArea.getFontMetrics(textArea.getFont())
.getFontRenderContext();
AttributedCharacterIterator charIt = text.getIterator();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc);
float formatWidth = (float) textArea.getSize().width;
lineMeasurer.setPosition(charIt.getBeginIndex());
int noLines = 0;
while (lineMeasurer.getPosition() < charIt.getEndIndex()) {
lineMeasurer.nextLayout(formatWidth);
noLines++;
}
return noLines;
}
}
【问题讨论】:
-
没人知道怎么做吗?
-
尝试使用 docs.oracle.com/javase/7/docs/api/javax/swing/… ,它返回显示整个文本所需的大小。
标签: java swing user-interface text resize