I am creating a JTable
in Netbeans and am having three minor issues with the structure.
- 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.
- The code I wrote to set the dimensions of the JTable do nothing if I change the variables.
- 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
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