Spacing errors while printing vector to JTextArea

100 views Asked by At

So I'm working on making a database system built on top of a Java Swing GUI... I have one button that works to add a person/thing to a vector (in this case the database):

// Database
Vector<String> db = new Vector<String>();

Here is the button's actionlistener to add:

new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        String newStudent = student.getText();
        db.addElement(newStudent);

This part all seems to be working fine, however, when I go to print out the vector on a JTextArea using a string buffer, there are odd spacing issues in the text on the JTextArea

Here is the StringBuffer and section where I print the vector onto the JTextArea:

StringBuffer dbb = new StringBuffer();
for (int i = 0; i < db.size(); i++) {
    dbb.append(db.get(i) + '\n');
}
// printDB is the JTextArea
printDB.setText(dbb.toString());
    add(printDB);

Screenshot of spacing issues: Screenshot

Any Ideas on what might be causing this? The spacing seems to be linear as well (1space, 2spaces, 3spaces...)

  • Link to full project if needed (Sorry for bad code in general lol i'm just beginning): Full Code

  • Sorry if linear isn't the right word btw I couldn't think of another way to describe it

Code:

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

public class Database extends JFrame implements ActionListener, EventListener {

   // Database
   Vector<String> db = new Vector<String>();

   // Main Menu Buttons:
   JButton addStudent = new JButton("Add Student");
   JButton deleteStudent = new JButton("Delete Button");
   JButton deleteAll = new JButton("Delete All Students");
   JButton printAll = new JButton("Print Database");
   JTextArea welcome = new JTextArea("Welcome!");

   // Add Student Menu:
   JTextField student = new JTextField();
   JButton submit = new JButton("Add Student");

   // Print Students
   JTextArea printDB = new JTextArea();
   JButton returnMenu = new JButton("Return to Menu");

   public Database() {
      super("DatabaseGUI");
      setSize(800, 600);

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLayout(null);
      setResizable(false);
      welcome.setBackground(this.getForeground());
      add(welcome);
      welcome.setSize(60, 15);
      welcome.setLocation(386, 300);
      add(addStudent);
      addStudent.setSize(150, 50);
      addStudent.setLocation(25, 100);
      add(deleteStudent);
      deleteStudent.setSize(150, 50);
      deleteStudent.setLocation(625, 100);
      add(deleteAll);
      deleteAll.setLocation(225, 100);
      deleteAll.setSize(150, 50);
      add(printAll);
      printAll.setLocation(425, 100);
      printAll.setSize(150, 50);
      addStudent.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            welcome.setVisible(false);
            addStudent.setVisible(false);
            deleteStudent.setVisible(false);
            deleteAll.setVisible(false);
            printAll.setVisible(false);
            add(student);
            add(submit);
            submit.setVisible(true);
            submit.setSize(150, 30);
            submit.setLocation(425, 250);
            student.setVisible(true);
            student.setSize(150, 30);
            student.setLocation(275, 250);
            submit.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                  String newStudent = student.getText();
                  db.addElement(newStudent);
                  student.setText(null);
                  student.setVisible(false);
                  submit.setVisible(false);
                  welcome.setVisible(true);
                  addStudent.setVisible(true);
                  deleteStudent.setVisible(true);
                  deleteAll.setVisible(true);
                  printAll.setVisible(true);
               }
            });
         }
      });
      printAll.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            welcome.setVisible(false);
            addStudent.setVisible(false);
            deleteStudent.setVisible(false);
            deleteAll.setVisible(false);
            printAll.setVisible(false);
            StringBuffer dbb = new StringBuffer();
            for (int i = 0; i < db.size(); i++) {
               dbb.append(db.get(i) + '\n');
            }
            printDB.setText(dbb.toString());
            add(printDB);
            printDB.setSize(300, 400);
            printDB.setEditable(false);
            printDB.setLocation(100, 100);
            printDB.setVisible(true);
            add(returnMenu);
            returnMenu.setVisible(true);
            returnMenu.setSize(200, 30);
            returnMenu.setLocation(500, 400);
            returnMenu.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent e) {
                  returnMenu.setVisible(false);
                  printDB.setVisible(false);
                  welcome.setVisible(true);
                  addStudent.setVisible(true);
                  deleteStudent.setVisible(true);
                  deleteAll.setVisible(true);
                  printAll.setVisible(true);
               }
            });
         }
      });
      setVisible(true);
   }

   public static void main(String[] args) {
      Database student = new Database();
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      // TODO Auto-generated method stub

   }

}
1

There are 1 answers

3
Hovercraft Full Of Eels On BEST ANSWER

You're adding an ActionListener to the submit button repeatedly within the addStudent ActionListener, meaning as addStudent is pressed, more and more ActionListeners will be added to submit and this is not what you want.

Suggestions:

  • Add an ActionListener just once to your JButtons and not within other event listeners which may be called multiple times. Consider adding all ActionListeners within your class constructor.

Side recs:

  • Don't use absolute positioning and null layouts. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
  • Learn how to use and then use CardLayout to allow you to cleanly and easily swap your views.

For example,

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class Database2 extends JPanel {
   // constants for the cards
   public static final String WELCOME = "welcome";
   public static final String ADD_STUDENT = "add student";
   public static final String DISPLAY_DATA = "display data";

   private JTextArea displayTextArea = new JTextArea(15, 20);
   private JTextField addStudentField = new JTextField(10);
   private CardLayout cardLayout = new CardLayout();
   private List<String> db = new ArrayList<>();

   public Database2() {
      // prepare JTextArea
      displayTextArea.setWrapStyleWord(true);
      displayTextArea.setLineWrap(true);
      displayTextArea.setFocusable(false);

      // set layout as CardLayout and add all JPanels with constants
      setLayout(cardLayout);
      add(createWelcomePanel(), WELCOME);
      add(createAddStudentPanel(), ADD_STUDENT);
      add(createDisplayDataPanel(), DISPLAY_DATA);
   }

   private JPanel createWelcomePanel() {
      ShowStudentPanelAction showStudentAction = new ShowStudentPanelAction("Add Student");
      DisplayDataAction displayDataAction = new DisplayDataAction("Display Data");
      JButton addStudentButton = new JButton(showStudentAction);
      JButton displayDataButton = new JButton(displayDataAction);

      JPanel topPanel = new JPanel(new GridLayout(1, 0, 5, 0));
      topPanel.add(addStudentButton);
      topPanel.add(displayDataButton);
      topPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));

      JLabel welcomeLabel = new JLabel("Welcome", SwingConstants.CENTER);
      // make JLabel text bigger
      welcomeLabel.setFont(welcomeLabel.getFont().deriveFont(Font.BOLD, 42f));

      // and give it a border 30 points wide
      int ebGap = 30;
      welcomeLabel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap,
            ebGap, ebGap));

      JPanel welcomePanel = new JPanel(new BorderLayout());
      ebGap = 4;
      welcomePanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
      welcomePanel.add(topPanel, BorderLayout.PAGE_START);
      welcomePanel.add(welcomeLabel, BorderLayout.CENTER);

      return welcomePanel;
   }

   private JPanel createAddStudentPanel() {
      AddStudentAction addStudentAction = new AddStudentAction("Add Student");
      addStudentField.setAction(addStudentAction);
      JPanel addStudentPanel = new JPanel();
      addStudentPanel.add(addStudentField);
      addStudentPanel.add(new JButton(addStudentAction)); 
      return addStudentPanel;
   }

   private JPanel createDisplayDataPanel() {
      JPanel displayDataPanel = new JPanel();
      JScrollPane scrollPane = new JScrollPane(displayTextArea);
      scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
      displayDataPanel.add(scrollPane);
      displayDataPanel.add(new JButton(new ReturnToWelcomeAction("Return")));
      return displayDataPanel;
   }

   private class ShowStudentPanelAction extends AbstractAction {
      public ShowStudentPanelAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         cardLayout.show(Database2.this, ADD_STUDENT);
         addStudentField.requestFocusInWindow();
         addStudentField.selectAll();
      }
   }

   private class DisplayDataAction extends AbstractAction {
      public DisplayDataAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         StringBuilder sb = new StringBuilder();
         for (String studentName : db) {
            sb.append(studentName + "\n");
         }
         displayTextArea.setText(sb.toString());
         cardLayout.show(Database2.this, DISPLAY_DATA);
      }
   }

   private class AddStudentAction extends AbstractAction {
      public AddStudentAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         String studentText = addStudentField.getText();
         db.add(studentText);
         cardLayout.show(Database2.this, WELCOME);
      }
   }

   private class ReturnToWelcomeAction extends AbstractAction {
      public ReturnToWelcomeAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         cardLayout.show(Database2.this, WELCOME);
      }
   }

   private class ExitAction extends AbstractAction {
      public ExitAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         Window window = SwingUtilities.getWindowAncestor(Database2.this);
         if (window != null) {
            window.dispose();
         }
      }
   }

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

      JFrame frame = new JFrame("Database2");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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