Home > database >  How to manually align, change size, and add scroll pane of JTable?
How to manually align, change size, and add scroll pane of JTable?

Time:02-12

I am creating a JTable in Netbeans and am having three minor issues with the structure.

  1. I can't seem to align my table in the direction I want (Say North, East, South, or West) and now it's annoyingly hovering over my JButton.
  2. The code I wrote to set the dimensions of the JTable do nothing if I change the variables.
  3. The code I wrote to add a JScrollPane is not showing up when I run it.

I understand if you can't solve all three but I figured I'd put them all in one instead of three different questions so any help with a problem is appreciated!

**Also as a note, ignore everything after the ActionListener. I am eventually going to make the code read a text file and sort that data in an ArrayList. Then somehow into the table instead of how I manually set it up in this example.

Here is my code (problem areas are labeled in comments in bold, capitalized font):

Main:

package libraryinventory;
 
import javax.swing.JFrame;
import java.io.*;

public class MainClass {

    static String[] bookArray;
        
    public static void main(String[] args) {
        
        GUICommandFunctions guiDemo = new GUICommandFunctions();
        //What to do when window closes
        guiDemo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // size of window in pixels
        guiDemo.setSize(1000, 720); 
        //make window visible
        guiDemo.setVisible(true);
        
    }
        
}

GUI Class:

package libraryinventory;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.*;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Box;
import static javax.swing.Box.createHorizontalBox;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;


public class GUICommandFunctions extends JFrame {
    
    private JButton ButtonOne;
    private JTable jt;
    
    public GUICommandFunctions() { 
        
        this.setTitle("Library Inventory"); //Name of window
     
        JPanel panel = new JPanel();  
        this.add(panel, BorderLayout.CENTER); //Location of panel for JButton

        ButtonOne = LibraryContentButton();
        panel.add(ButtonOne); //adding panel to JFrame

        
        String[] columns = {"Title", "Author/Language", "Publisher", "Page Count", "Version Number/Genre/Topic", "Part of a series/Illustrator"}; //columns of the JTable
        String[][] data = {{"The Keto Cookbook", "Chronicle Books", "304", "English", "Keto Cooking", "null"}, //data under the columns
                           {"The Hitchhiker's Guide to the Galaxy", "Del Rey", "224", "Douglas Adams", "Fantasy", "Y"}      
        };
        
        jt = new JTable(data, columns){ //Makes it so can't edit data inside table once ran
            public boolean isCellEditable(int data, int columns) {
                    return false;
            }
        };
        
        jt.setPreferredScrollableViewportSize(new Dimension(450, 63)); //Set size. **HERE IS PROBLEM #2**
        jt.setFillsViewportHeight(true); //Set visible
        jt.setVerticalAlignment(JTable.BOTTOM_ALIGNMENT); //**HERE IS PROBLEM #1**
        
        JScrollPane jps = new JScrollPane(jt); //add scroll **HERE IS PROBLEM #3**
        add(jps);
        
    }
    
        private JButton LibraryContentButton() { //
            JButton content = new JButton("Click to view all content");
            content.setFocusable(false);
            content.setBackground(Color.DARK_GRAY);
            content.setForeground(Color.WHITE);
            content.setFont(new Font("Arial", Font.BOLD, 20));
            content.setToolTipText("Shows content of the entire library in a neatly ordered JTable");
            content.setMargin(new Insets(10, 10, 10, 10));
            content.setPreferredSize(new Dimension(300, 75));

            
            
            content.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(rootPane, "Eventually will make this button load up the JTable");              
                }
            });
            return content;
     
        }

    static {
    
        int arrayCount;
      
        FileReader fr = null;
        
        try {
            fr = new FileReader("C:\\Users\\Mark Case\\Documents\\NetBeansProjects\\LibraryInventory\\src\\libraryinventory\\library.txt"); //Reads in text file
        } catch (FileNotFoundException ex) {
            Logger.getLogger(GUICommandFunctions.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        BufferedReader reader = new BufferedReader(fr);       
        ArrayList<String> str = new ArrayList<>();
        String line = "";
        arrayCount = 0;
        try {
            while((line=reader.readLine())!=null) {
                str.add(line);
                arrayCount = arrayCount   1;
                
            }
        } catch (IOException ex) {
            Logger.getLogger(GUICommandFunctions.class.getName()).log(Level.SEVERE, null, ex);
        }

        // Here we would actually set the type to what the user wants (note: Set it to a "0" if the user wants all Books)
        String selType = "2";  
        
        // Call method to select Books by category type
        String methodResult = SelectType(str, arrayCount, selType);
        
    }  

    private static String SelectType (ArrayList<String> str, int arrayCount, String selType) {
        for (int i = 1; i < arrayCount; i  ) {
           
            String buffer = str.get(i);
            String bookCat = buffer.substring(0,1);
            
            // Print books by Category - "0" type means print all Books
            if (selType.equals(bookCat)) {
                System.out.println(buffer);
            }          
            else if (selType.equals("0")) {
                System.out.println(buffer);
            }
        }
        return "0";   
    }



}

CodePudding user response:

So, let's take a quick look at the constructor...

public GUICommandFunctions() { 
    //...
    JPanel panel = new JPanel();  
    this.add(panel, BorderLayout.CENTER); //Location of panel for JButton

    ButtonOne = LibraryContentButton();
    panel.add(ButtonOne); //adding panel to JFrame
    //...
    jt.setPreferredScrollableViewportSize(new Dimension(450, 63)); //Set size. **HERE IS PROBLEM #2**
    jt.setFillsViewportHeight(true); //Set visible
    jt.setVerticalAlignment(JTable.BOTTOM_ALIGNMENT); //**HERE IS PROBLEM #1**
    
    JScrollPane jps = new JScrollPane(jt); //add scroll **HERE IS PROBLEM #3**
    add(jps);
}

You add panel to the CENTER. Since you've extended directly from JFrame, the layout is already BorderLayout, so this is fine.

But then you add jps using add(jps);, which will add the component to the layouts default position, which in the case of BorderLayout is CENTER. This is problematic, as BorderLayout only allows a single component to be managed at each position, which explains why you're setPreferredScrollableViewportSize isn't working, as the BorderLayout is ignoring it, and making the component fill the available space in the CENTER

So, I modified your code. First, I extended from JPanel instead of JFrame. It's generally discouraged to extend from JFrame directly, you're not adding any new functionality to the class, locking yourself into a single use case and it generally just makes you live more difficult.

Secondly, I placed the JScrollPane at the SOUTH position of the BorderLayout

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new GUICommandFunctionsPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class GUICommandFunctionsPane extends JPanel {

        private JButton ButtonOne;
        private JTable jt;

        public GUICommandFunctionsPane() {
            setLayout(new BorderLayout());
            JPanel panel = new JPanel();
            this.add(panel, BorderLayout.CENTER); //Location of panel for JButton

            ButtonOne = LibraryContentButton();
            panel.add(ButtonOne); //adding panel to JFrame

            String[] columns = {"Title", "Author/Language", "Publisher", "Page Count", "Version Number/Genre/Topic", "Part of a series/Illustrator"}; //columns of the JTable
            String[][] data = {{"The Keto Cookbook", "Chronicle Books", "304", "English", "Keto Cooking", "null"}, //data under the columns
            {"The Hitchhiker's Guide to the Galaxy", "Del Rey", "224", "Douglas Adams", "Fantasy", "Y"}
            };

            jt = new JTable(data, columns) { //Makes it so can't edit data inside table once ran
                public boolean isCellEditable(int data, int columns) {
                    return false;
                }
            };

            jt.setPreferredScrollableViewportSize(new Dimension(450, 63)); //Set size. **HERE IS PROBLEM #2**
            jt.setFillsViewportHeight(true); //Set visible

            JScrollPane jps = new JScrollPane(jt);
            add(jps, BorderLayout.SOUTH);

        }

        private JButton LibraryContentButton() { //
            JButton content = new JButton("Click to view all content");
            content.setFocusable(false);
            content.setBackground(Color.DARK_GRAY);
            content.setForeground(Color.WHITE);
            content.setFont(new Font("Arial", Font.BOLD, 20));
            content.setToolTipText("Shows content of the entire library in a neatly ordered JTable");
            content.setMargin(new Insets(10, 10, 10, 10));
            content.setPreferredSize(new Dimension(300, 75));

            content.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(GUICommandFunctionsPane.this, "Eventually will make this button load up the JTable");
                }
            });
            return content;

        }

//        static {
//
//            int arrayCount;
//
//            FileReader fr = null;
//
//            try {
//                fr = new FileReader("C:\\Users\\Mark Case\\Documents\\NetBeansProjects\\LibraryInventory\\src\\libraryinventory\\library.txt"); //Reads in text file
//            } catch (FileNotFoundException ex) {
//                Logger.getLogger(GUICommandFunctionsPane.class.getName()).log(Level.SEVERE, null, ex);
//            }
//
//            BufferedReader reader = new BufferedReader(fr);
//            ArrayList<String> str = new ArrayList<>();
//            String line = "";
//            arrayCount = 0;
//            try {
//                while ((line = reader.readLine()) != null) {
//                    str.add(line);
//                    arrayCount = arrayCount   1;
//
//                }
//            } catch (IOException ex) {
//                Logger.getLogger(GUICommandFunctionsPane.class.getName()).log(Level.SEVERE, null, ex);
//            }
//
//            // Here we would actually set the type to what the user wants (note: Set it to a "0" if the user wants all Books)
//            String selType = "2";
//
//            // Call method to select Books by category type
//            String methodResult = SelectType(str, arrayCount, selType);
//
//        }
//
//        private static String SelectType(ArrayList<String> str, int arrayCount, String selType) {
//            for (int i = 1; i < arrayCount; i  ) {
//
//                String buffer = str.get(i);
//                String bookCat = buffer.substring(0, 1);
//
//                // Print books by Category - "0" type means print all Books
//                if (selType.equals(bookCat)) {
//                    System.out.println(buffer);
//                } else if (selType.equals("0")) {
//                    System.out.println(buffer);
//                }
//            }
//            return "0";
//        }
    }
}

Oh, and I would discourage you from using a static initialiser this way, instead, this either needs to go into the constructor, or, you should use some form of dependency injection to pass the information to the class

  • Related