以下类实现了chatGUI。正常运行时,屏幕如下所示:
精美的ChatGUI
http://img21.imageshack.us/img21/7177/rightchat.jpg
当我输入较大长度的文本时,问题经常出现。50到100个字符的gui变得疯狂。聊天记录框如下所示缩小
图片http://img99.imageshack.us/img99/6962/errorgui.jpg。
关于什么原因的任何想法?
谢谢。
PS:下面的附加类是完整的代码。您可以复制它并在计算机上进行编译,以确切地了解我的意思。
注意:一旦GUI变得疯狂,那么如果我单击“清除”按钮,历史记录窗口将清除,并且GUI返回到再次正确显示。
package Sartre.Connect4;
import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.text.StyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.BadLocationException;
import java.io.BufferedOutputStream;
import javax.swing.text.html.HTMLEditorKit;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JFileChooser;
/**
* Chat form class
* @author iAmjad
*/
public class ChatGUI extends JDialog implements ActionListener {
/**
* Used to hold chat history data
*/
private JTextPane textPaneHistory = new JTextPane();
/**
* provides scrolling to chat history pane
*/
private JScrollPane scrollPaneHistory = new JScrollPane(textPaneHistory);
/**
* used to input local message to chat history
*/
private JTextPane textPaneHome = new JTextPane();
/**
* Provides scrolling to local chat pane
*/
private JScrollPane scrollPaneHomeText = new JScrollPane(textPaneHome);
/**
* JLabel acting as a statusbar
*/
private JLabel statusBar = new JLabel("Ready");
/**
* Button to clear chat history pane
*/
private JButton JBClear = new JButton("Clear");
/**
* Button to save chat history pane
*/
private JButton JBSave = new JButton("Save");
/**
* Holds contentPane
*/
private Container containerPane;
/**
* Layout GridBagLayout manager
*/
private GridBagLayout gridBagLayout = new GridBagLayout();
/**
* GridBagConstraints
*/
private GridBagConstraints constraints = new GridBagConstraints();
/**
* Constructor for ChatGUI
*/
public ChatGUI(){
setTitle("Chat");
// set up dialog icon
URL url = getClass().getResource("Resources/SartreIcon.jpg");
ImageIcon imageIcon = new ImageIcon(url);
Image image = imageIcon.getImage();
this.setIconImage(image);
this.setAlwaysOnTop(true);
setLocationRelativeTo(this.getParent());
//////////////// End icon and placement /////////////////////////
// Get pane and set layout manager
containerPane = getContentPane();
containerPane.setLayout(gridBagLayout);
/////////////////////////////////////////////////////////////
//////////////// Begin Chat History //////////////////////////////
textPaneHistory.setToolTipText("Chat History Window");
textPaneHistory.setEditable(false);
textPaneHistory.setPreferredSize(new Dimension(350,250));
scrollPaneHistory.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPaneHistory.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// fill Chat History GridBagConstraints
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 10;
constraints.gridheight = 10;
constraints.weightx = 100;
constraints.weighty = 100;
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.CENTER;
constraints.insets = new Insets(10,10,10,10);
constraints.ipadx = 0;
constraints.ipady = 0;
gridBagLayout.setConstraints(scrollPaneHistory, constraints);
// add to the pane
containerPane.add(scrollPaneHistory);
/////////////////////////////// End Chat History ///////////////////////
///////////////////////// Begin Home Chat //////////////////////////////
textPaneHome.setToolTipText("Home Chat Message Window");
textPaneHome.setPreferredSize(new Dimension(200,50));
textPaneHome.addKeyListener(new MyKeyAdapter());
scrollPaneHomeText.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPaneHomeText.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// fill Chat History GridBagConstraints
constraints.gridx = 0;
constraints.gridy = 10;
constraints.gridwidth = 6;
constraints.gridheight = 1;
constraints.weightx = 100;
constraints.weighty = 100;
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.CENTER;
constraints.insets = new Insets(10,10,10,10);
constraints.ipadx = 0;
constraints.ipady = 0;
gridBagLayout.setConstraints(scrollPaneHomeText, constraints);
// add to the pane
containerPane.add(scrollPaneHomeText);
////////////////////////// End Home Chat /////////////////////////
///////////////////////Begin Clear Chat History ////////////////////////
JBClear.setToolTipText("Clear Chat History");
// fill Chat History GridBagConstraints
constraints.gridx = 6;
constraints.gridy = 10;
constraints.gridwidth = 2;
constraints.gridheight = 1;
constraints.weightx = 100;
constraints.weighty = 100;
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.CENTER;
constraints.insets = new Insets(10,10,10,10);
constraints.ipadx = 0;
constraints.ipady = 0;
gridBagLayout.setConstraints(JBClear, constraints);
JBClear.addActionListener(this);
// add to the pane
containerPane.add(JBClear);
///////////////// End Clear Chat History ////////////////////////
/////////////// Begin Save Chat History //////////////////////////
JBSave.setToolTipText("Save Chat History");
constraints.gridx = 8;
constraints.gridy = 10;
constraints.gridwidth = 2;
constraints.gridheight = 1;
constraints.weightx = 100;
constraints.weighty = 100;
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.CENTER;
constraints.insets = new Insets(10,10,10,10);
constraints.ipadx = 0;
constraints.ipady = 0;
gridBagLayout.setConstraints(JBSave, constraints);
JBSave.addActionListener(this);
// add to the pane
containerPane.add(JBSave);
///////////////////// End Save Chat History /////////////////////
/////////////////// Begin Status Bar /////////////////////////////
constraints.gridx = 0;
constraints.gridy = 11;
constraints.gridwidth = 10;
constraints.gridheight = 1;
constraints.weightx = 100;
constraints.weighty = 50;
constraints.fill = GridBagConstraints.BOTH;
constraints.anchor = GridBagConstraints.CENTER;
constraints.insets = new Insets(0,10,5,0);
constraints.ipadx = 0;
constraints.ipady = 0;
gridBagLayout.setConstraints(statusBar, constraints);
// add to the pane
containerPane.add(statusBar);
////////////// End Status Bar ////////////////////////////
// set resizable to false
this.setResizable(false);
// pack the GUI
pack();
}
/**
* Deals with necessary menu click events
* @param event
*/
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
// Process Clear button event
if (source == JBClear){
textPaneHistory.setText(null);
statusBar.setText("Chat History Cleared");
}
// Process Save button event
if (source == JBSave){
// process only if there is data in history pane
if (textPaneHistory.getText().length() > 0){
// process location where to save the chat history file
JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(false);
chooser.setAcceptAllFileFilterUsed(false);
FileNameExtensionFilter filter = new FileNameExtensionFilter("HTML Documents", "htm", "html");
chooser.setFileFilter(filter);
int option = chooser.showSaveDialog(ChatGUI.this);
if (option == JFileChooser.APPROVE_OPTION) {
// Set up document to be parsed as HTML
StyledDocument doc = (StyledDocument)textPaneHistory.getDocument();
HTMLEditorKit kit = new HTMLEditorKit();
BufferedOutputStream out;
try {
// add final file name and extension
String filePath = chooser.getSelectedFile().getAbsoluteFile() + ".html";
out = new BufferedOutputStream(new FileOutputStream(filePath));
// write out the HTML document
kit.write(out, doc, doc.getStartPosition().getOffset(), doc.getLength());
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(ChatGUI.this,
"Application will now close. \n A restart may cure the error!\n\n"
+ e.getMessage(),
"Fatal Error",
JOptionPane.WARNING_MESSAGE, null);
System.exit(2);
} catch (IOException e){
JOptionPane.showMessageDialog(ChatGUI.this,
"Application will now close. \n A restart may cure the error!\n\n"
+ e.getMessage(),
"Fatal Error",
JOptionPane.WARNING_MESSAGE, null);
System.exit(3);
} catch (BadLocationException e){
JOptionPane.showMessageDialog(ChatGUI.this,
"Application will now close. \n A restart may cure the error!\n\n"
+ e.getMessage(),
"Fatal Error",
JOptionPane.WARNING_MESSAGE, null);
System.exit(4);
}
statusBar.setText("Chat History Saved");
}
}
}
}
/**
* Process return key for sending the message
*/
private class MyKeyAdapter extends KeyAdapter {
@Override
@SuppressWarnings("static-access")
public void keyPressed(KeyEvent ke) {
//DateTime dateTime = new DateTime();
//String nowdateTime = dateTime.getDateTime();
int kc = ke.getKeyCode();
if (kc == ke.VK_ENTER) {
try {
// Process only if there is data
if (textPaneHome.getText().length() > 0){
// Add message origin formatting
StyledDocument doc = (StyledDocument)textPaneHistory.getDocument();
Style style = doc.addStyle("HomeStyle", null);
StyleConstants.setBold(style, true);
String home = "Home [" + nowdateTime + "]: ";
doc.insertString(doc.getLength(), home, style);
StyleConstants.setBold(style, false);
doc.insertString(doc.getLength(), textPaneHome.getText() + "\n", style);
// update caret location
textPaneHistory.setCaretPosition(doc.getLength());
textPaneHome.setText(null);
statusBar.setText("Message Sent");
}
} catch (BadLocationException e) {
JOptionPane.showMessageDialog(ChatGUI.this,
"Application will now close. \n A restart may cure the error!\n\n"
+ e.getMessage(),
"Fatal Error",
JOptionPane.WARNING_MESSAGE, null);
System.exit(1);
}
ke.consume();
}
}
}
}
首先有很多一般性评论:
a)发布代码时发布SSCCE。如果您不知道什么是SSCCE,请搜索论坛或网络。我们只有有限的时间来查看代码,而300行的代码太多了。例如:
b)使用正确的Java命名约定。变量名以小写字母开头。“ JBSave”和“ JBClear”不是标准名称,这会使您的代码难以读取。
c)我也同意Gridbaglayout很复杂,并且其他布局管理器(如前面给出的BorderLayout方法)更易于使用。具体来说,您对gridx和gridy的理解不正确。它们应用于指示“顺序”的行和列位置。也就是说,您应该使用(0,0),(0,1),(1,1),(2,1)。您的网格数跳到10。10不能反映相对大小。因此,您缺少行1、2、3、4、5、6、7
…是的,它可能会起作用,但是在阅读代码时却难以理解。
d)不要使用KeyListener来处理文本窗格中的Enter键。Swing被设计为使用“键绑定”。阅读Swing教程中有关同一主题的部分,以获取更多信息。
最后,对代码的修复很简单:
textPaneHome.setToolTipText("Home Chat Message Window");
// textPaneHome.setPreferredSize(new Dimension(200,50));
textPaneHome.addKeyListener(new MyKeyAdapter());
scrollPaneHomeText.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPaneHomeText.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPaneHomeText.setPreferredSize(new Dimension(200,50));
通常,永远不要设置添加到滚动窗格的组件的首选大小。在这种情况下,将文本设置为null时,首选大小将重置为0,并且所有组件的布局似乎都已重做。
我的应用程序:有两个活动,一个创建两个字符串(名称和消息),这两个字符串被保存到hashmap中,传输到JSON中,并保存在SharedPreference中。另一个活动获取这个SharedPreference,再次将其转移到hashmap中。然后地图被迭代器“读出”。 应该是:我的想法是,如果我多次执行这个过程,迭代器就会“读出”HashMap中的所有条目。
编辑:我已经回答了这个问题,代码已经被更改,所以它是可用的,请在您自己的项目中随意使用代码。你好,利亚姆 我目前正在LWJGL中进行3D模型渲染,我遇到了一个问题,当我运行程序时,显示会出现,并且一切都与模型无关。我测试了3D空间代码,绘制了一些随机点,我可以看到它们并四处走动,所以我的3D空间代码正在工作,但模型代码不行。 我的问题如下:我的显示代码有问题吗?还是我的模型加载代码有问题?下面是我
我有一个svg的xml代码,这段代码可以在edge、chrome浏览器正常打开并显示出svg绘制的内容,而当我用firefox打开的时候,页面却是一片空白,这是什么原因造成的以及如何修复使得firefox上也可以正常显示。 firefox的版本 edge上 firefox上
问题内容: 我有这个查询: 我得到这个结果: 如果您看不到()列,我该怎么做才能按顺序显示数字? 问题答案: 如果查询包含,则必须在外部查询中添加行号。
有没有人能帮我一下这个如何用下面的数据来实现。
怎么颜色是这样的,一开始我都以为没字,可以改吗?