Reputation: 19
I am trying to make a notepad like application in java.
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. 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.
Upvotes: 0
Views: 222
Reputation: 51445
I created a JFrame
with a JTextPane
and a JTextArea
.
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.
I start the application with a call to the SwingUtilities
invokeLater
method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
I use Swing layout managers. This is crucial. There's no way you can build a complex Swing GUI without using layout managers. No way. Inconceivable.
The JFrame
has a default BorderLayout
. I put the main JPanel
in the CENTER. When you create the status JPanel
, you can place that JPanel
AFTER_LAST_LINE.
I create a main JPanel
, a line number JPanel
, and a text area JPanel
. Almost any GUI can be broken down into multiple JPanels
. Once you get the hang of it, you see JPanels
everywhere.
I create each JPanel
in its own method. 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.
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.
Did I mention how important Swing layout managers are to creating a 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) {
}
}
}
Upvotes: 1