【问题标题】:JTextArea with JScrollPAne within Frame with null LayoutJTextArea 与 JScrollPAne 在 Frame 内具有空布局
【发布时间】:2016-03-16 04:02:07
【问题描述】:

我正在尝试将这个带有 JScrollPane(带有垂直但不是水平滚动条)的 JTextArea 添加到我的框架中,但结果只是一个灰色区域,右侧有一个滚动条......我可能正在做一些非常愚蠢的事情但我已经对 JPanel 做了同样的事情,它确实有效

public class Chats {

     public static int height = 600;
     public static int length = 400;

     public static void init(String me, String you){

         JFrame frame = new JFrame ("Chat");
         frame.setSize(larguraframe, alturaframe);
         frame.setLocation(620, 100);
         frame.setResizable(false);
         frame.setLayout(null);
         frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

         JTextArea chat = new JTextArea();
         chat.setColumns(10);
         chat.setLineWrap(true);
         chat.setWrapStyleWord(true);
         JScrollPane scrollpane = new JScrollPane(chat, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER;  
         scrollpane.setBounds(length/8 - 27, height/9 + 27, 350, 380);
         chat.setPreferredSize(new Dimension(lenght-15, 7*height/8-27));

         frame.add(chat);
         frame.add(scrollpane);
         frame.setVisible(true);
     }

 }

我不介意更改框架的布局,但我真的想要一个可以让我将东西准确放置在我想要的位置的布局。谢谢


编辑

好的,它现在显示在我的框架上,但 TextArea 仍然无法调整大小。当我使用 JTextfield 和带有侦听器的 JButton 在其中写入内容时,该侦听器将 JTextfield 的文本附加到 JTextArea,然后将 JTextField 中的文本设置为“”,它最多只能接受一定数量的行。在那之后,它看起来还是一样的。

【问题讨论】:

  • 请您发布您的输出图片...
  • 您的代码也包含多个错误...其中一行的长度拼写错误。
  • @ITguy 谢谢,但那是因为我在上传之前翻译了它。
  • 因为这条线,它无法调整大小:frame.setResizable(false);
  • 1) 从不设置JTextArea的preferredSize,除非你想创建一个在需要时不会添加额外行的JTextArea。而是设置 JTextArea 的行和列属性。

标签: java swing chat jscrollpane


【解决方案1】:

我知道你已经“接受”了一个答案,但我觉得如果我没有给出一个给出重要观点的答案,我会失职,从长远来看,这些答案会让你创建一个更好、更健壮(即更易于调试、可修改和可增强)的应用程序。

再次,

  1. 永远不要设置JTextArea 的preferredSize,因为这将创建一个大小设置不灵活的JTextArea,在需要时不会添加额外的行。而是设置 JTextArea 的行和列属性。
  2. 虽然空布局和setBounds() 在 Swing 新手看来是创建复杂 GUI 的最简单和最好的方法,但创建的 Swing GUI 越多,使用它们时遇到的困难就越严重。当 GUI 调整大小时,它们不会调整您的组件大小,它们是增强或维护的皇家女巫,放置在滚动窗格中时它们完全失败,在与原始不同的所有平台或屏幕分辨率上查看时它们看起来很糟糕.
  3. 最好使用一个 JPanel,或者更经常使用多个嵌套的 JPanel,每个 JPanel 都使用自己的布局管理器,让您可以更简单地创建灵活、功能强大的复杂而美观的 GUI。
  4. 使用布局管理器时,您需要在添加所有组件后pack() 您的 JFrame,以便所有布局管理器都能正确完成其工作和布局组件。

我在下面展示了一个示例程序,

  • 带有大文本的标题 JLabel
  • 一个 JTextArea,称为 chatViewArea,具有指定的行和列大小,保存在 JScrollPane 中,用于查看聊天。它是不可聚焦的,因此用户无法直接与之交互。
  • 另一个 JTextArea,称为 textEntryArea,用于输入文本。您可以为此使用一个简单的 JTextField 并为其提供一个 ActionListener 以便它响应回车键,但是如果您想要一个行为相似的多行文本组件,您需要更改 JTextArea 的回车键的键绑定.我在这里这样做是为了让 enter 键“提交”textEntryArea JTextArea 中保存的文本,并且 control-enter 组合键的作用与用于创建新行的 enter 键相同。
  • 主 JPanel 仅使用 BorderLayout 来允许将标题放置在顶部,将聊天视图 JTextArea 放置在中心,将文本条目 JTextArea 放置在底部。请注意,如果您需要查看更多组件,例如显示其他聊天的 JList,可以通过嵌套 JPanel 并在需要时使用更多布局来完成。

例如:

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;    
import javax.swing.*;

@SuppressWarnings("serial")
public class Chat2 extends JPanel {
    private static final int ROWS = 25; // rows in the chat view JTextArea
    private static final int COLS = 40; // columns in the chat view JTextArea
                                        // and text entry area
    private static final int ENTRY_ROWS = 4; // rows in the text entry JTextArea
    private static final int BL_HGAP = 10; // horizontal gap for our
                                           // BorderLayout
    private static final int BL_VGAP = 5; // vertical gap for our BorderLayout
    private static final int EB_GAP = 15; // gap for empty border that goes
                                          // around entire app
    private static final String TITLE_TEXT = "My Chat Application";
    private static final float TITLE_POINTS = 32f; // size of the title jlabel
                                                   // text
    private JTextArea chatViewArea = new JTextArea(ROWS, COLS);
    private JTextArea textEntryArea = new JTextArea(ENTRY_ROWS, COLS);

    public Chat2() {
        // label to display the title in bold large text
        JLabel titleLabel = new JLabel(TITLE_TEXT, SwingConstants.CENTER);
        titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, TITLE_POINTS));

        // set up the chat view JTextArea to have word wrap
        // and to not be focusable
        chatViewArea.setWrapStyleWord(true);
        chatViewArea.setLineWrap(true);
        chatViewArea.setFocusable(false);

        // add it to a JScrollPane, and give the scrollpane vertical scrollbars
        JScrollPane viewScrollPane = new JScrollPane(chatViewArea);
        viewScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        // set up the text entry JTextArea
        textEntryArea.setWrapStyleWord(true);
        textEntryArea.setLineWrap(true);

        // key bindings so that control-enter will act as enter and the enter key will "submit"
        // the user input to the chat window and the chat server
        // will allow us to use a multilined text entry area if desired instead
        // of a single lined JTextField
        setEnterKeyBinding(textEntryArea);

        JScrollPane entryScrollPane = new JScrollPane(textEntryArea);
        entryScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        // add an empty border around entire application
        setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
        // make the main layout a BorderLayout
        setLayout(new BorderLayout(BL_HGAP, BL_VGAP));
        // add our components to the GUI
        add(titleLabel, BorderLayout.PAGE_START);
        add(viewScrollPane, BorderLayout.CENTER);
        add(entryScrollPane, BorderLayout.PAGE_END);
    }

    // Again, use key bindings so that control-enter JTextArea will act as enter key
    // and the enter key will "submit" the user input to the chat window and the chat server.
    // When ctrl-enter is pushed the Action originally bound to the enter key will be called
    // and when enter is pushed a new Action, the EnterKeyAction, will be called
    private void setEnterKeyBinding(JTextArea textArea) {
        int condition = JComponent.WHEN_FOCUSED; // only for focused entry key
        InputMap inputMap = textArea.getInputMap(condition);
        ActionMap actionMap = textArea.getActionMap();

        KeyStroke entryKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
        KeyStroke ctrlEntryKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK);

        // first give ctrl-enter the action held by enter
        Object entryKey = inputMap.get(entryKeyStroke);
        Action entryAction = actionMap.get(entryKey);
        inputMap.put(ctrlEntryKeyStroke, ctrlEntryKeyStroke.toString());
        actionMap.put(ctrlEntryKeyStroke.toString(), entryAction);

        // now give enter key a new Action
        EnterKeyAction enterKeyAction = new EnterKeyAction();
        inputMap.put(entryKeyStroke, entryKeyStroke.toString());
        actionMap.put(entryKeyStroke.toString(), enterKeyAction);
    }

    public void appendToChatArea(final String text) {
        if (SwingUtilities.isEventDispatchThread()) {
            chatViewArea.append(text + "\n");
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    chatViewArea.append(text + "\n");
                }
            });
        }
    }

    private class EnterKeyAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            String text = textEntryArea.getText();
            textEntryArea.setText("");

            chatViewArea.append("User: " + text + "\n");

            // TODO send text to the chat server!

        }
    }

    private static void createAndShowGui() {
        Chat2 mainPanel = new Chat2();

        JFrame frame = new JFrame("My Chat Window");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);

        // pack the JFrame so that it will size itself to its components
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    尝试设置这样的布局:

    frame.setLayout(new BorderLayout());
    

    并将滚动窗格添加到中心:

    frame.add(scrollpane, BorderLayout.CENTER);
    

    同时删除 Jire 在他的回答中指出的那一行。

    【讨论】:

    • 我真的不喜欢这个样子
    【解决方案3】:

    chat不用加,因为是scrollPane改编的。

    删除此行:frame.add(chat);

    【讨论】:

      【解决方案4】:

      添加

      chat.setBounds(length/8 - 27, height/9 + 27, 330, 360);
      

      并看到神奇的发生......但为了得到正确的尺寸,请在这里讨论参数。

      对于可调整大小的框架,只需使用 frame.setResizable(true); 而不是 frame.setResizable(false);

      【讨论】:

      • 我实际上已经评论了这一行,但这没有用,它仍然无法调整大小,但是谢谢!真的!
      猜你喜欢
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多