【问题标题】:Adding JScrollPane in JTextArea using GridBagLayout使用 GridBagLayout 在 JTextArea 中添加 JScrollPane
【发布时间】:2013-08-29 04:56:36
【问题描述】:

我在使用 GridBagLayout 在 JTextArea 中添加 JScrollPane 时遇到问题。基本上,当不需要滚动条时程序运行良好,但布局变得混乱,内容在需要时被切断。相关代码如下

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

public class testGUI extends JFrame
{
    public static String name;
    static JTextField textfield = new JTextField(30);
    static JTextArea  textarea = new JTextArea(30,30);

    public static void main( String[] args)
    {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Checkem");
        frame.setLocation(500,400);
        frame.setSize(800,800);

        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        JScrollPane scrolltxt = new JScrollPane(textarea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrolltxt.setWheelScrollingEnabled(true); 
        scrolltxt.getVerticalScrollBar().isVisible();
        panel.add(scrolltxt, c); 

        JLabel label = new JLabel("Enter the Name of the file:");
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(2,2,2,2);

        panel.add(label,c);

        c.gridx = 0;
        c.gridy = 1;
        panel.add(textarea,c);      

        JButton button = new JButton("Search");
        c.gridx = 1;
        c.gridy = 1;
        panel.add(button,c);

        c.gridx = 1;
        c.gridy = 0;
        panel.add(textfield,c);


        frame.getContentPane().add(panel, BorderLayout.NORTH);
        frame.pack();
        frame.setVisible(true);

        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                Checkem record = new Checkem();
                name = textfield.getText();         
                String [] print = record.run(name);

                for (int i=0;i<print.length;i++)
                {
                    if(print[i] == null || print[i].isEmpty())
                    {
                        continue;
                    }
                    else
                    {
                        textarea.append(print[i] + "\n");
                    }
                }
            }
        });

    }
}

我对挥杆真的很陌生,我真的不知道从这里往哪里走。感谢您的所有帮助。

【问题讨论】:

  • 为什么不简单地使用tArea.setLineWrap(true) and tArea.setWrapStyleWord(true) 而不是定义ScrollBar 策略,这在视图上甚至看起来不错:-) 请学习Java 命名约定并坚持下去,这会变得有点困难当有人在 Java 代码中使用非常规术语来理解代码时,乍一看:(
  • 此外,不要将JTextArea 添加到JPanel,而是将scrolltxt 添加到相同的位置,因为JTextArea 已经放置在JScrollPane 内:-)

标签: java swing jscrollpane jtextarea gridbaglayout


【解决方案1】:

现在到实际的东西:-)

  • 为什么不简单地使用JTextArea.setLineWrap(true)JTextArea.setWrapStyleWord(true) 而不是定义 JScrollBar 策略, 这甚至在视图上看起来不错:-)
  • 此外,不指定setSize()/setLocation() 方法, 只需使用frameReference.pack()frame.setLocationByPlatform(true),很精彩的回答 关于后者的好处在这个答案中提到,how to best position Swing GUIs
  • 不要在一个类中创建这么多静态字段,这闻起来很糟糕 编程设计,并降低您的类的可扩展性。
  • 您将 JFrame 扩展到您的 TestGUI 类,然后在里面 这是您创建相同实例的main() 方法。实际上 再次,尝试赋予组合更多的权重而不是继承,因为 在这里,您实际上并没有尝试修改已经定义的 JFrame 的功能,而不是您按原样使用它们,所以有 至少在这种情况下不需要扩展JFrame :-)
  • 阅读Concurrency in Swing

这是你修改后的代码:

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

public class TestGUI {

    private String name;
    private JTextField textfield = new JTextField(30);
    private JTextArea  textarea = new JTextArea(30,30);

    private void displayGUI() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Checkem");        

        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        textarea.setLineWrap(true);
        textarea.setWrapStyleWord(true);
        JScrollPane scrolltxt = new JScrollPane();
        scrolltxt.setViewportView(textarea);
        scrolltxt.setWheelScrollingEnabled(true);

        JLabel label = new JLabel("Enter the Name of the file:");
        c.gridx = 0;
        c.gridy = 0;
        c.insets = new Insets(2,2,2,2);

        panel.add(label,c);

        c.gridx = 0;
        c.gridy = 1;
        panel.add(scrolltxt,c);      

        JButton button = new JButton("Search");
        c.gridx = 1;
        c.gridy = 1;
        panel.add(button,c);

        c.gridx = 1;
        c.gridy = 0;
        panel.add(textfield,c);


        frame.getContentPane().add(panel, BorderLayout.NORTH);      
        //frame.setSize(800,800);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                /*Checkem record = new Checkem();
                name = textfield.getText();         
                String [] print = record.run(name);

                for (int i=0;i<print.length;i++)
                {
                    if(print[i] == null || print[i].isEmpty())
                    {
                        continue;
                    }
                    else
                    {
                        textarea.append(print[i] + "\n");
                    }
                }*/
            }
        });
    }

    public static void main( String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                new TestGUI().displayGUI();
            }
        };
        EventQueue.invokeLater(r);
    }
}

【讨论】:

    【解决方案2】:

    您添加了 JScrollPane,但随后您将 JLabel 添加到了相同的网格位置。然后您稍后添加没有 JScrollPane 的原始 JTextArea。

    试试这个,它只添加包含你的 JTextArea 的 JScrollPane。我还将您的 GUI 创建移到了一个构造函数中,该构造函数通过 SwingUtilities.invokeLater 调用来调用,以确保它在 EDT 上。有关 EDT 的更多详细信息,请参阅Concurrency in Swing。这也允许您不必将所有类成员变量都设为静态,这不是很好的做法。

    import java.awt.BorderLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    
    public class TestGUI extends JFrame {
    
        String name;
        JTextField textfield = new JTextField(30);
        JTextArea textarea = new JTextArea(30, 30);
    
        public TestGUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            JPanel panel = new JPanel(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();
            JScrollPane scrolltxt = new JScrollPane(textarea);
    
            JLabel label = new JLabel("Enter the Name of the file:");
            c.gridx = 0;
            c.gridy = 0;
            c.insets = new Insets(2, 2, 2, 2);
    
            panel.add(label, c);
            c.gridx = 0;
            c.gridy = 1;
            panel.add(scrolltxt, c);
    
            JButton button = new JButton("Search");
            c.gridx = 1;
            c.gridy = 1;
            panel.add(button, c);
    
            c.gridx = 1;
            c.gridy = 0;
            panel.add(textfield, c);
    
            frame.getContentPane().add(panel, BorderLayout.NORTH);
            frame.pack();
            frame.setVisible(true);
    
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    Checkem record = new Checkem();
                    name = textfield.getText();
                    String [] print = record.run(name);
    
                    for (int i=0;i<print.length;i++) {
                        if(print[i] == null || print[i].isEmpty()) {
                            continue;
                        } else {
                            textarea.append(print[i] + "\n");
                        }
                    }
                }
            });
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new TestGUI();
                }
            });
        }
    }
    

    【讨论】:

    • +1 for DISPOSE_ON_CLOSE 和其他有价值的输入 :-),虽然这次投票将在 7 小时内完成,因为我的限制已经结束了 :(
    • 感谢您的努力。不幸的是,滚动条仍然无法正常工作,但我真的很感谢清理我的一些错误代码。我刚刚使用了 nIcE cOw 建议的 JTextArea.setLineWrap(true) 和 JTextArea.setWrapStyleWord(true) ,它就像一个魅力。
    猜你喜欢
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多