简体   繁体   English

如何将 JTextPane 和 JTextArea 添加到 JScrollPane?

[英]How do you add both JTextPane and JTextArea to a JScrollPane?

I am trying to make a notepad like application in java.我正在尝试在 java 中制作类似记事本的应用程序。

Something like this:像这样的东西: 在此处输入图像描述

I want to have the part on the side with the line numbers ( JTextArea ) and the text part ( JTextPane ) and I want to add scroll to them both.我想将部分放在带有行号( JTextArea )和文本部分( JTextPane )的一侧,并且我想为它们都添加滚动。 This is my program right now.这是我现在的程序。

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(-7, -1, 550, 400);
contentPane = new JPanel();
contentPane.setBounds(-7, -1, 550, 400);
setContentPane(contentPane);
contentPane.setLayout(null);
        
JPanel Pane=new JPanel();
Pane.setLayout(null);
        
JTextPane txtp = new JTextPane();
txtp.setFont(new Font("Segoe UI", Font.PLAIN, 11));
txtp.setBounds(22, 0, 413, 250);
Pane.add(txtp);
        
JTextArea header = new JTextArea();
header.setBounds(0, 0, 20, 250);
Pane.add(header);
        
JScrollPane txt=new JScrollPane(Pane);
txt.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
txt.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
txt.setBounds(0, 0, 437, 250);
txt.getVerticalScrollBar().setOpaque(false);
txt.getHorizontalScrollBar().setOpaque(false);
contentPane.add(txt);

count = new JTextField();
count.setText("Word Count: 0,        Character Count: 0");
count.setFont(new Font("Segoe UI", Font.PLAIN, 9));
count.setBounds(0, 250, 439, 13);
contentPane.add(count);
count.setColumns(10);

Any help would be thanked for.任何帮助将不胜感激。

I created a JFrame with a JTextPane and a JTextArea .我用JTextPaneJTextArea创建了一个JFrame

基本字处理器 GUI

As you can see, there are line numbers, a text area, and a scroll bar.如您所见,有行号、文本区域和滚动条。

Here are the steps I took to create this GUI.以下是我创建此 GUI 所采取的步骤。

  1. I start the application with a call to the SwingUtilities invokeLater method.我通过调用SwingUtilities invokeLater方法来启动应用程序。 This method ensures that the Swing components are created and executed on the Event Dispatch Thread .此方法确保在Event Dispatch Thread上创建和执行 Swing 组件。

  2. I use Swing layout managers .我使用Swing 布局管理器 This is crucial.这是至关重要的。 There's no way you can build a complex Swing GUI without using layout managers.如果不使用布局管理器,您将无法构建复杂的 Swing GUI。 No way.没门。 Inconceivable.不可思议。

  3. The JFrame has a default BorderLayout . JFrame有一个默认的BorderLayout I put the main JPanel in the CENTER.我将主JPanel放在中心。 When you create the status JPanel , you can place that JPanel AFTER_LAST_LINE.创建状态JPanel时,可以将该JPanel放在 AFTER_LAST_LINE 之后。

  4. I create a main JPanel , a line number JPanel , and a text area JPanel .我创建了一个主JPanel 、一个行号JPanel和一个文本区域JPanel Almost any GUI can be broken down into multiple JPanels .几乎任何 GUI 都可以分解为多个JPanels Once you get the hang of it, you see JPanels everywhere.一旦你掌握了窍门,你就会到处看到JPanels

  5. I create each JPanel in its own method.我以自己的方法创建每个JPanel This is a separation of concerns.这是关注点分离。 This allows me to focus on one part of the GUI at a time and allows me to experiment with different Swing layout managers to see which layout manager works best.这使我可以一次专注于 GUI 的一个部分,并允许我尝试使用不同的 Swing 布局管理器来查看哪个布局管理器效果最好。

Here's the complete runnable code.这是完整的可运行代码。 You may use this as a basis to start your application, adding a tiny, tiny bit of code at a time, and testing.您可以以此为基础来启动您的应用程序,一次添加一小部分代码并进行测试。 Test, test, test.测试,测试,测试。 Testing is the only way you learn how to use Swing layout managers.测试是您学习如何使用 Swing 布局管理器的唯一方法。

Did I mention how important Swing layout managers are to creating a GUI?我有没有提到 Swing 布局管理器对于创建 GUI 有多重要? Well, they are.嗯,他们是。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;

public class BasicWordProcessor implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new BasicWordProcessor());
    }
    
    private int rows;
    
    private Document document;
    
    private JTextArea textArea;
    
    private JTextPane textPane;
    
    public BasicWordProcessor() {
        this.rows = 15;
        this.document = new PlainDocument();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Basic Word Processor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMainPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        
        JPanel innerPanel = new JPanel(new BorderLayout());
        
        innerPanel.add(createLineNumberPanel(), 
                BorderLayout.BEFORE_LINE_BEGINS);
        innerPanel.add(createTextAreaPanel(), BorderLayout.CENTER);
        
        JScrollPane scrollPane = new JScrollPane(innerPanel);
        
        Dimension d = innerPanel.getPreferredSize();
        d.width += 30;
        panel.setPreferredSize(d);
        
        panel.add(scrollPane, BorderLayout.CENTER);
        
        return panel;
    }
    
    private JPanel createLineNumberPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        
        textPane = new JTextPane();
        textPane.setEditable(false);
        
        createRowText();
        
        panel.add(textPane);
        
        return panel;
    }

    private void createRowText() {
        int length = Integer.toString(rows).length();
        String formatter = "%0" + length + "d";
        StringBuilder builder = new StringBuilder();
        
        for (int i = 1; i <= rows; i++) {
            String s = String.format(formatter, i);
            builder.append(s).append(System.lineSeparator());
        }
        
        textPane.setText(builder.toString());
    }
    
    private JPanel createTextAreaPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        
        textArea = new JTextArea(document, "", rows, 60);
        document.addDocumentListener(new MyDocumentListener());
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        panel.add(textArea);
        
        return panel;
    }
    
    public class MyDocumentListener implements DocumentListener {

        @Override
        public void insertUpdate(DocumentEvent event) {
            rows = textArea.getLineCount();
            createRowText();
        }

        @Override
        public void removeUpdate(DocumentEvent event) {
            rows = textArea.getLineCount();
            createRowText();
        }

        @Override
        public void changedUpdate(DocumentEvent event) {
            
        }
        
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM