My code outputs the correct answer to both the GUI and to a text file, but it displays it in a list format instead of a clean looking table. What modifications have to be made to assign formatting of output correctly?

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.GridLayout;
import java.awt.event.*;
import java.sql.*;
import java.io.*;

public class DataBase extends JFrame implements ActionListener 
{
  //global variables used throughout program. Establish gui interface and output
  //variable to display results to screen.
  JButton submitQuery = new JButton("Submit Query");              
  JButton saveQuery = new JButton("Save Query");
  JTextField queryField = new JTextField(25);
  JTextArea queryResults = new JTextArea(5, 20);
  JScrollPane scrollPane = new JScrollPane(queryResults);
  String gui_output;
 
 public DataBase()
 {
  //create organization layout for gui
  JPanel northpanel = new JPanel();
  JPanel southpanel = new JPanel();
  JPanel eastpanel = new JPanel();
  eastpanel.setLayout(new GridLayout(1,2));
    
  southpanel.setBorder(new TitledBorder("Query Results"));
  
  //action listeners for gui buttons
  submitQuery.addActionListener(this);
  saveQuery.addActionListener(this);
  queryField.addActionListener(this);
  
  northpanel.add(queryField);
  eastpanel.add(submitQuery);
  eastpanel.add(saveQuery);
  southpanel.add(queryResults);
  
  add(northpanel, BorderLayout.NORTH);
  add(southpanel, BorderLayout.SOUTH);
  add(eastpanel, BorderLayout.EAST);
 }
 
 public void actionPerformed(ActionEvent e)
 {
  //establish connection to database
  Connection connection;
  
  
  Statement stmt;
  
  //assign driver
  try
  {
   Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
   System.out.println("Drive loaded");
  }
  catch (java.lang.ClassNotFoundException f)
  {
   System.err.print("ClassNotFoundException: ");
	System.err.println(f.getMessage());
  }
  
  //connect to skiclub database
  try
  {
   connection = DriverManager.getConnection("jdbc:odbc:skiclub");

   System.out.println("Database connected");
   stmt = connection.createStatement();
   String query = queryField.getText();
	   
	ResultSet resultSet = stmt.executeQuery(query);
	
	ResultSetMetaData rsMetaData = resultSet.getMetaData();
	for (int i = 1; i <= rsMetaData.getColumnCount(); i++)
	 {
	  //System.out.printf("%-12s\t", rsMetaData.getColumnName(i));
	  // gather and format column names for display
     gui_output += String.format("%-30s\t", rsMetaData.getColumnName(i));
     // gather carriage-return and newline character display     
	  gui_output += "\r\n";
	  queryResults.append(gui_output);
	 } 
	System.out.println();
	
	while (resultSet.next())
	{
	 for (int i = 1; i <= rsMetaData.getColumnCount(); i++)
	  {
	   // System.out.printf("%-12s\t", resultSet.getObject(i));
	   // gather and format data rows for display
      gui_output += String.format("%-30s\t", resultSet.getObject(i));
      // gather carriage-return and newline character for row display
      gui_output += "\r\n";
		queryResults.append(gui_output);
	  }
	 System.out.println();
	}
	
   stmt.close();
   connection.close();
   }
   catch(SQLException ex)
   {
    System.err.print("SQLException: ");
	 System.err.println(ex.getMessage());
   }
	
	FileOutputStream out; // declare a file output object
   PrintStream p; // declare a print stream object

   try
   {
     // Create a new file output stream
     // connected to "myfile.txt"
     out = new FileOutputStream("results.txt");

     // Connect print stream to the output stream
     p = new PrintStream( out );
		
     p.println (gui_output);

     p.close();
   }
   catch (Exception g)
   {
     System.err.println ("Error writing to file");
   }
 }
 
  
 public static void main(String[] args)
 {
  DataBase frame = new DataBase();
  //set the window title
  frame.setTitle("JAVA ITP220 - DataBase Program");
  //set the window location
  frame.setLocationRelativeTo(null);
  //specify what happens when the close button is clicked
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //set the window size
  frame.setSize(600, 250);
  //display the window
  frame.setVisible(true);
 }
}

Dani AI

Generated

Short version: is right — use a JTable for tabular display. JTable gives column headers, proper alignment, resizing, sorting and cell renderers that a JTextArea cannot replicate. Below is a compact, modern approach: convert the ResultSet into a DefaultTableModel, set that model on a JTable inside a JScrollPane, and write the same model to a file if needed.

A few important problems in the original post to note before switching components:

  • gui_output is declared but never initialized; using += on it will throw a NullPointerException.
  • Appending a CRLF inside the inner loop causes each cell to appear on its own line instead of one row per record. Build a full row string and append a single newline after the row if staying with JTextArea.
  • Long-running DB work is done on the Event Dispatch Thread (actionPerformed) and will freeze the UI; run queries on a background thread (SwingWorker) and update the table on the EDT.
  • Use try-with-resources to close Connection/Statement/ResultSet and prefer PreparedStatement when query text comes from users.

Example helper (add imports for javax.swing.table.DefaultTableModel and java.util.Vector):

public static DefaultTableModel buildTableModel(ResultSet rs) throws SQLException {
    ResultSetMetaData meta = rs.getMetaData();
    int colCount = meta.getColumnCount();

    Vector<String> colNames = new Vector<>(colCount);
    for (int i = 1; i <= colCount; i++) {
        colNames.add(meta.getColumnLabel(i));
    }

    Vector<Vector<Object>> data = new Vector<>();
    while (rs.next()) {
        Vector<Object> row = new Vector<>(colCount);
        for (int i = 1; i <= colCount; i++) {
            row.add(rs.getObject(i));
        }
        data.add(row);
    }

    return new DefaultTableModel(data, colNames);
}

Usage notes: construct the model on a background thread, then on the EDT create JTable table = new JTable(model); table.setAutoCreateRowSorter(true); and put it in a JScrollPane. To export results, iterate the model and write CSV or tab-separated lines with a PrintWriter (try-with-resources). If keeping a JTextArea for quick debugging, set a monospaced font and format each row with a single String.format call so columns line up.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.