So I am attempting to make a basic GUI using Java Swing. I have some buttons, a text field with an enter button and also a larger text area. When clicking the button "Display all teams", the action listener for this button should output the JTable content onto the text area, however it isn't working and nothing is outputting.
package footballmanager;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JTextPane;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JScrollBar;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
public class FootballGUI
{
private JFrame frame;
private JTextField textField;
//Launch the application.
public static void main(String[] args)
{
FootballGUI window = new FootballGUI();
window.frame.setVisible(true);
}
//Display the application
public void displayGUI() {
this.frame.setVisible(true);
}
//Create the application.
public FootballGUI()
{
frame = new JFrame();
frame.setBounds(100, 100, 611, 471);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Text area
final JTextArea testArea = new JTextArea(5,20);
testArea.setBounds(6, 6, 329, 343);
frame.getContentPane().add(testArea);
// Buttons on the window
JButton displayTeams = new JButton("Display all teams");
// (x, y, w, h)
displayTeams.setBounds(370, 6, 200, 29);
frame.getContentPane().add(displayTeams);
class MyActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
// String s = String.format("%s %s", "Club name", "Club points");
// testArea.setText(s);
String[] columnNames = {"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};
Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)},
{"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};
JTable table = new JTable(data, columnNames);
DefaultTableModel model1 = (DefaultTableModel) table.getModel();
int nRow = model1.getRowCount(), nCol = model1.getColumnCount();
Object [][] tableData = new Object [nRow] [nCol];
for (int i = 0; i < nRow; i++){
for (int j = 0; j < nCol; j++){
tableData [i][j] = model1.getValueAt (i,j);
testArea.append((String) tableData [i][j] + "\t");
}
}
testArea.append("\n");
}
}
displayTeams.addActionListener(new MyActionListener());
JButton goalSort = new JButton("Sort list by goals");
goalSort.setBounds(370, 40, 200, 29);
frame.getContentPane().add(goalSort);
JButton winSort = new JButton("Sort list by most wins");
winSort.setBounds(370, 74, 200, 29);
frame.getContentPane().add(winSort);
JButton randomMatch = new JButton("Generate random match");
randomMatch.setBounds(370, 280, 200, 29);
frame.getContentPane().add(randomMatch);
JButton displayMatches = new JButton("Display all played matches");
displayMatches.setBounds(370, 314, 200, 29);
frame.getContentPane().add(displayMatches);
JButton btnEnter = new JButton("Search for a match");
btnEnter.setBounds(518, 404, 85, 39);
frame.getContentPane().add(btnEnter);
JScrollBar scrollBar = new JScrollBar();
scrollBar.setBounds(320, 6, 15, 338);
frame.getContentPane().add(scrollBar);
textField = new JTextField();
textField.setBounds(5, 410, 508, 28);
frame.getContentPane().add(textField);
textField.setColumns(10);
JLabel lblMapGoesHere = new JLabel("List goes here");
lblMapGoesHere.setBounds(342, 37, 263, 312);
frame.getContentPane().add(lblMapGoesHere);
}
}
I redid your GUI to use a JTable.
Here's what the revised GUI looks like.
Here's what it looks like after you left-click on the "Display All Teams" button.
Here are the major changes I made to your GUI.
I started the Java application with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and used on the Event Dispatch Thread.
I used Swing layout managers for the two JPanels I created. The JFrame content pane uses a default BorderLayout. The JTable JPanel uses the default FlowLayout. the JButton JPanel uses a GridBagLayout. The fixed layout you used wouldn't let me adjust the size of the JTextArea you were using.
I used a JTable to display the teams. I put the JTable in a JScrollPane, and the JScrollPane inside a JPanel.
I created the columns and data before I created the GUI. Generally, you want to create the application model first, then the GUI. This is a simple example of the model / view / controller pattern.
Here's the complete runnable code I used.
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
public class FootballGUI implements Runnable {
private DefaultTableModel model;
private JFrame frame;
private JTable table;
private String[][] data;
// Launch the application.
public static void main(String[] args) {
SwingUtilities.invokeLater(new FootballGUI());
}
public FootballGUI() {
String[] columnNames = { "First Name", "Last Name", "Sport",
"# of Years", "Vegetarian" };
this.model = new DefaultTableModel();
for (String s : columnNames) {
model.addColumn(s);
}
this.data = new String[][] { { "Kathy", "Smith", "Snowboarding", "5", "false" },
{ "John", "Doe", "Rowing", "3", "true" },
{ "Sue", "Black", "Knitting", "2", "false" },
{ "Jane", "White", "Speed reading", "20", "true" },
{ "Joe", "Brown", "Pool", "10", "false" } };
}
// Create the application.
#Override
public void run() {
frame = new JFrame("Football GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTablePanel(), BorderLayout.CENTER);
frame.add(createButtonPanel(), BorderLayout.AFTER_LINE_ENDS);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTablePanel() {
JPanel panel = new JPanel();
table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
panel.add(scrollPane);
return panel;
}
private JPanel createButtonPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.weightx = 1.0d;
JButton displayTeams = new JButton("Display all teams");
displayTeams.addActionListener(new MyActionListener());
panel.add(displayTeams, gbc);
gbc.gridy++;
JButton goalSort = new JButton("Sort list by goals");
panel.add(goalSort, gbc);
gbc.gridy++;
JButton winSort = new JButton("Sort list by most wins");
panel.add(winSort, gbc);
gbc.gridy++;
JButton randomMatch = new JButton("Generate random match");
panel.add(randomMatch, gbc);
gbc.gridy++;
JButton displayMatches = new JButton("Display all played matches");
panel.add(displayMatches, gbc);
gbc.gridy++;
JButton btnEnter = new JButton("Search for a match");
panel.add(btnEnter, gbc);
return panel;
}
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
int count = model.getRowCount();
for (int i = 0; i < count; i++) {
model.removeRow(0);
}
for (int i = 0; i < data.length; i++) {
model.addRow(data[i]);
}
}
}
}
however it isn't working
Well, you have a ClassCastException. Don't you think it is important to put that information in the question?
JTable table = new JTable(data, columnNames);
DefaultTableModel model1 = (DefaultTableModel) table.getModel();
int nRow = model1.getRowCount(), nCol = model1.getColumnCount();
Object [][] tableData = new Object [nRow] [nCol];
for (int i = 0; i < nRow; i++){
for (int j = 0; j < nCol; j++){
tableData [i][j] = model1.getValueAt (i,j);
testArea.append((String) tableData [i][j] + "\t");
}
}
What is the point of logic like above?
Why would you add data to a JTable where the data is displayed nicely formatted and then attempt to copy and display it in a JTextArea, where the data is not formatted?
Why would you take data from the model and attempt to add the data to a 2D Array?
Why are you even trying to access the TableModel?
You can just get the information from the JTable directly. All you need is:
//testArea.append((String) tableData [i][j] + "\t");
testArea.append( table.getValueAt(i, j).toString() + "\t" )?
Of course you will also need two loops, one for rows and one for columns.
Related
I'm having a problem with a JFrame not showing a JTable that is added to it. I've tried getContentPane().add(..), I've switched to just add to keep the code a little shorter. Any help is more than appreciated!
package com.embah.Accgui;
import java.awt.*;
import javax.swing.*;
public class accCreator extends JFrame {
private String[] columnNames = {"Username", "Password", "Members", "World"};
private Object[][] data = {{"b", "b", "b", "b"},
{ "e", "e", "e", "e"}};
private JTable tbl_Accounts;
private JScrollPane scrollPane;
private JLabel lbl_Account = new JLabel();
private JLabel lbl_Username = new JLabel();
private JLabel lbl_Password = new JLabel();
private JLabel lbl_Homeworld = new JLabel();
private JButton btn_Select = new JButton();
private JButton btn_Addacc = new JButton();
private JButton btn_Delacc = new JButton();
private JTextArea txt_Username = new JTextArea();
private JTextArea txt_Password = new JTextArea();
private JTextArea txt_Homeworld = new JTextArea();
private JCheckBox cbox_Members = new JCheckBox();
private JCheckBox cbox_RanWrld = new JCheckBox();
public accCreator() {
setLayout(null);
setupGUI();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void setupGUI() {
tbl_Accounts = new JTable(data, columnNames);
tbl_Accounts.setLocation(5, 30);
tbl_Accounts.setPreferredScrollableViewportSize(new Dimension(420, 250));
tbl_Accounts.setFillsViewportHeight(true);
tbl_Accounts.setVisible(true);
add(tbl_Accounts);
scrollPane = new JScrollPane(tbl_Accounts);
add(scrollPane);
lbl_Account.setLocation(4, 5);
lbl_Account.setSize(100, 20);
lbl_Account.setText("Select Account:");
add(lbl_Account);
lbl_Username.setLocation(5, 285);
lbl_Username.setSize(70, 20);
lbl_Username.setText("Username:");
add(lbl_Username);
lbl_Password.setLocation(5, 310);
lbl_Password.setSize(70, 20);
lbl_Password.setText("Password:");
add(lbl_Password);
lbl_Homeworld.setLocation(310, 310);
lbl_Homeworld.setSize(80, 20);
lbl_Homeworld.setText("Home World:");
add(lbl_Homeworld);
btn_Select.setLocation(305, 5);
btn_Select.setSize(120, 20);
btn_Select.setText("Select Account");
add(btn_Select);
btn_Addacc.setLocation(300, 285);
btn_Addacc.setSize(60, 20);
btn_Addacc.setText("Add");
btn_Addacc.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
String worldSel = "";
if(cbox_RanWrld.isSelected()){
worldSel = "Random";
} else {
worldSel = txt_Homeworld.getText();
}
Object[] row = {txt_Username.getText(), txt_Password.getText(), cbox_Members.isSelected(), worldSel};
DefaultTableModel model = (DefaultTableModel) tbl_Accounts.getModel();
model.addRow(row);
}
});
add(btn_Addacc);
btn_Delacc.setLocation(365, 285);
btn_Delacc.setSize(60, 20);
btn_Delacc.setText("Del");
btn_Delacc.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
DefaultTableModel model = (DefaultTableModel) tbl_Accounts.getModel();
}
});
add(btn_Delacc);
txt_Username.setLocation(80, 285);
txt_Username.setSize(100, 20);
txt_Username.setText("");
txt_Username.setRows(5);
txt_Username.setColumns(5);
add(txt_Username);
txt_Password.setLocation(80, 310);
txt_Password.setSize(100, 20);
txt_Password.setText("");
txt_Password.setRows(5);
txt_Password.setColumns(5);
txt_Password.setTabSize(0);
add(txt_Password);
txt_Homeworld.setLocation(395, 310);
txt_Homeworld.setSize(30, 20);
txt_Homeworld.setText("82");
txt_Homeworld.setRows(5);
txt_Homeworld.setColumns(5);
txt_Homeworld.setTabSize(0);
add(txt_Homeworld);
cbox_Members.setLocation(185, 285);
cbox_Members.setSize(80, 20);
cbox_Members.setText("Members");
cbox_Members.setSelected(false);
add(cbox_Members);
cbox_RanWrld.setLocation(185, 310);
cbox_RanWrld.setSize(115, 20);
cbox_RanWrld.setText("Random World");
cbox_RanWrld.setSelected(false);
add(cbox_RanWrld);
setTitle("Account Manager");
setSize(440, 370);
setVisible(true);
setResizable(false);
}
public static void main(String args[]) {
new accCreator();
}
}
I know thats not the problem tho because everything else shows up just fine
Oh... really? Not in my computer...
Let's have a picture of your actual GUI shown in my PC:
Does the GUI looks the same in your computer? I bet no.
But... why does it looks like that in my PC?
Well, as stated above in the comments by #MadProgrammer this is because of the setLayout(null); line. You might want to read Why is it frowned upon to use a null layout in Java Swing? for more information.
Now, that being said, you should also want to read and learn how to use the various layout managers that will let you create complex GUIs.
In your code you never set the location / bounds for scrollPane, and the size of it, so the component has a default size of 0, 0.
But... I think it's better to show you how you can get a really similar GUI (I'm in a hurry so I didn't make an even more similar GUI). You can copy-paste my code and see the same output (with slight differences because of the OS maybe) but text won't be cropped.
The code that produces the above image is this one:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class AccountCreator {
private JFrame frame;
private JPanel mainPane;
private JPanel topPane;
private JPanel tablePane;
private JPanel bottomPane;
private JLabel selectAccountLabel;
private JLabel userNameLabel;
private JLabel passwordLabel;
private JLabel homeWorldLabel;
private JTextField userNameField;
private JTextField homeWorldField;
private JPasswordField passwordField;
private JCheckBox membersBox;
private JCheckBox randomBox;
private JButton selectAccountButton;
private JButton addButton;
private JButton deleteButton;
private JTable table;
private JScrollPane scroll;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new AccountCreator().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
int rows = 30;
int cols = 3;
String[][] data = new String[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
data[i][j] = i + "-" + j;
}
}
String[] columnNames = { "Column1", "Column2", "Column3" };
table = new JTable(data, columnNames);
scroll = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
table.setPreferredScrollableViewportSize(new Dimension(420, 250));
table.setFillsViewportHeight(true);
selectAccountLabel = new JLabel("Select Account");
userNameLabel = new JLabel("Username: ");
passwordLabel = new JLabel("Password: ");
homeWorldLabel = new JLabel("Home world");
selectAccountButton = new JButton("Select Account");
addButton = new JButton("Add");
deleteButton = new JButton("Del");
userNameField = new JTextField(10);
passwordField = new JPasswordField(10);
homeWorldField = new JTextField(3);
membersBox = new JCheckBox("Members");
randomBox = new JCheckBox("Random world");
topPane = new JPanel();
topPane.setLayout(new BorderLayout());
topPane.add(selectAccountLabel, BorderLayout.WEST);
topPane.add(selectAccountButton, BorderLayout.EAST);
tablePane = new JPanel();
tablePane.add(scroll);
bottomPane = new JPanel();
bottomPane.setLayout(new GridLayout(0, 5, 3, 3));
bottomPane.add(userNameLabel);
bottomPane.add(userNameField);
bottomPane.add(membersBox);
bottomPane.add(addButton);
bottomPane.add(deleteButton);
bottomPane.add(passwordLabel);
bottomPane.add(passwordField);
bottomPane.add(randomBox);
bottomPane.add(homeWorldLabel);
bottomPane.add(homeWorldField);
mainPane = new JPanel();
mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.PAGE_AXIS));
frame.add(topPane, BorderLayout.NORTH);
frame.add(tablePane, BorderLayout.CENTER);
frame.add(bottomPane, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Also, you might have noticed that the main() method is different, well, the code inside it is placing the program on the Event Dispatch Thread (EDT).
So, be sure to include it in your future programs
I am newbie of Swing.
I want to update table after click button (done button).
I think data correct but the screen does not work.
The followings are explanation of my program
check checkBoxes and the click Done button
the bottom layer should change.
there is no main
This is my code:
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import net.miginfocom.swing.MigLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Gui extends JFrame {
class Table extends JTable{
public Table(DefaultTableModel model) {
super(model);
}
public Class getColumnClass(int column) {
switch (column) {
case 1:
return Boolean.class;
default:
return String.class;
}
}
}
private final int BANDNUM = 43;
int[] checkBands;
Object[][] data;
Table table;
JScrollPane upperScrollpane;
JScrollPane downScrollPane;
JSplitPane splitPane;
public Gui() {
// BASE SETTING
setSize(900, 800);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout(5, 5));
JPanel northPanel = new JPanel(new MigLayout());
// northPanel SETTING
JLabel labelIp = new JLabel("IP");
JTextField tFIp = new JTextField(20);
JLabel labelMask = new JLabel("Subnet Mask");
JTextField tFMask = new JTextField(20);
JLabel labelPing = new JLabel("Ping");
JTextField tFPing = new JTextField(10);
JButton btnReady = new JButton("Ready");
JLabel labelReady = new JLabel("NOT READY");
northPanel.add(labelIp);
northPanel.add(tFIp);
northPanel.add(labelMask);
northPanel.add(tFMask);
northPanel.add(labelPing);
northPanel.add(tFPing);
northPanel.add(btnReady);
northPanel.add(labelReady, "wrap");
// upper scrollpane -> will be included in JsplitPane Upper Side
JPanel checkPanel = new JPanel(new MigLayout());
JCheckBox[] checkBoxes = new JCheckBox[BANDNUM];
JButton doneButton = new JButton("DONE");
for (int i = 0; i < BANDNUM; i++) {
checkBoxes[i] = new JCheckBox("" + (i + 1));
checkBoxes[i].setHorizontalTextPosition(SwingConstants.CENTER);
checkBoxes[i].setVerticalTextPosition(SwingConstants.BOTTOM);
if (i == 32) {
checkPanel.add(checkBoxes[i], "wrap");
} else if (i == 42) {
checkPanel.add(checkBoxes[i], "wrap");
} else {
checkPanel.add(checkBoxes[i]);
}
}
checkPanel.add(doneButton, "span 3");
// startButton Action
/////////////////////////////////////////
//I think you should watch from this line!!!
/////////////////////////////////////////
doneButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// 1. CHECK WHAT ARE CLICKED
int length = 0;
for (int i = 0; i < BANDNUM; i++)
if (checkBoxes[i].isSelected())
length++;
checkBands = new int[length];
System.out.println(length);
int k = 0;
for (int i = 0; i < BANDNUM; i++) {
if (checkBoxes[i].isSelected()) {
checkBands[k++] = i + 1;
}
}
// 2. Ready for display
data = new Object[length][6];
for (int i = 0; i < length; i++) {
data[i][0] = checkBands[i];
data[i][1] = true;
data[i][2] = 1;
data[i][3] = 2;
data[i][4] = 3;
data[i][5] = 4;
}
// 3. display
String[] colNames = { "BAND", "Test1", "Test2", "Test3",
"Test4", "Test5" };
DefaultTableModel model = new DefaultTableModel(data, colNames);
table = new Table(model);
setVisible(true);
table.repaint();
downScrollPane.repaint();
splitPane.repaint();
}
});
// down scrollpane -> will be included in JsplitPane down Side
String[] colNames = { "BAND", "Test1", "Test2", "Test3", "Test4",
"Test5" };
Object[][] data = { { null, null, null, null, null, null }};
DefaultTableModel model = new DefaultTableModel(data, colNames);
table = new Table(model);
// include
upperScrollpane = new JScrollPane(checkPanel);
downScrollPane = new JScrollPane(table);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upperScrollpane, downScrollPane);
mainPanel.add(northPanel, BorderLayout.NORTH);
mainPanel.add(splitPane, BorderLayout.CENTER);
getContentPane().add(mainPanel);
setVisible(true);
}
}
Instead of doing this...
String[] colNames = { "BAND", "Test1", "Test2", "Test3",
"Test4", "Test5" };
DefaultTableModel model = new DefaultTableModel(data, colNames);
table = new Table(model);
Simply update the existing model
DefaultTableModel model = (DefaultTableModel)table.getModel();
for (Object[] row : data) {
model.addRow(row);
}
or simply
DefaultTableModel model = (DefaultTableModel)table.getModel();
for (int i = 0; i < length; i++) {
data = new Object[6];
data[0] = checkBands[i];
data[1] = true;
data[2] = 1;
data[3] = 2;
data[4] = 3;
data[5] = 4;
model.addRow(data);
}
This assumes that you want to keep adding new rows to the table. You can also use model.setRowCount(0) to clear the table first and then add new rows to it, if that's what you want to.
Swing works a principle of MVC (Model-View-Controller) which separates the view (the JTable) from the data/model (TableModel), this means that the JTable is not bound to the data and can easily be changed or modified by simply changing or modifying the table's model. This is an important concept to understand, as Swing makes a great deal of use of this methodology
I have the following resizable form that consists of one main JPanel with 4 other JPanels that go inside. They will resize as the JFrame is resized.
I decided to see if I could put another class that creates a GUI into the top frame that is depicted in the image below.
I think that it might be that I am trying to put a JFrame into a JPanel that is already in JFrame.
Question: I want to put another GUI class (that makes a JTable) into a JPanel in another class?
Code:
package testpak;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.net.MalformedURLException;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ResizeTestGUI {
private JPanel jpPack;
private JPanel jpCards;
private JPanel jpInfo;
private JPanel jpChat;
private SimpleTableDemo std = new SimpleTableDemo();
public ResizeTestGUI() throws MalformedURLException {
final JFrame frame = new JFrame("Draft");
frame.setPreferredSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel IsMainJPanel = new JPanel();
IsMainJPanel.setLayout(new GridBagLayout());
jpCards = new JPanel(new BorderLayout());
jpCards.setBackground(Color.BLUE);
jpInfo = new JPanel();
jpInfo.setBackground(Color.GREEN);
jpPack = new JPanel(new GridBagLayout());
jpPack.setBackground(Color.RED);
jpChat = new JPanel();
jpChat.setBackground(Color.BLACK);
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.fill = GridBagConstraints.BOTH; // set it to fill both vertically and
// horizontally
c.gridx = 0;
c.gridy = 0;
c.weightx = 0.3;
c.weighty = 0.3;
jpCards.add(std);
IsMainJPanel.add(jpCards, c);
c.gridx = 1;
c.gridy = 0;
c.weightx = 0.3;
c.weighty = 0.3;
IsMainJPanel.add(jpInfo, c);
c.gridx = 0;
c.gridy = 1;
c.weightx = 0.3;
c.weighty = 0.3;
IsMainJPanel.add(jpPack, c);
c.gridx = 1;
c.gridy = 1;
c.weightx = 0.3;
c.weighty = 0.3;
IsMainJPanel.add(jpChat, c);
frame.setContentPane(IsMainJPanel);
frame.setLocationByPlatform(true);
frame.pack();
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
public static void main(String[] args) throws MalformedURLException {
ResizeTestGUI dg = new ResizeTestGUI();
}
}
Simple JTable example: (found on internet)
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class SimpleTableDemo extends JPanel {
private static final long serialVersionUID = 1L;
private boolean DEBUG = false;
public SimpleTableDemo() {
super(new GridLayout(1, 0));
String[] columnNames = { "First Name", "Last Name", "Sport", "# of Years",
"Vegetarian" };
Object[][] data = {
{ "Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false) },
{ "John", "Doe", "Rowing", new Integer(3), new Boolean(true) },
{ "Sue", "Black", "Knitting", new Integer(2), new Boolean(false) },
{ "Jane", "White", "Speed reading", new Integer(20), new Boolean(true) },
{ "Joe", "Brown", "Pool", new Integer(10), new Boolean(false) } };
final JTable table = new JTable(data, columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
if (DEBUG) {
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
printDebugData(table);
}
});
}
// Create the scroll pane and add the table to it.
JScrollPane scrollPane = new JScrollPane(table);
// Add the scroll pane to this panel.
add(scrollPane);
createAndShowGUI();
}
private void printDebugData(JTable table) {
int numRows = table.getRowCount();
int numCols = table.getColumnCount();
javax.swing.table.TableModel model = table.getModel();
System.out.println("Value of data: ");
for (int i = 0; i < numRows; i++) {
System.out.print(" row " + i + ":");
for (int j = 0; j < numCols; j++) {
System.out.print(" " + model.getValueAt(i, j));
}
System.out.println();
}
System.out.println("--------------------------");
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
}
Error:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.Exception.<init>(Exception.java:102)
at java.lang.ReflectiveOperationException.<init>(ReflectiveOperationException.java:89)
at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:72)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Sourc
You have created a cyclic dependencies of the object SimpleTableDemo as shown below that results into StackOverflowError
Constructor -> Method -> Constructor -> Method -> ...
public SimpleTableDemo() {
super(new GridLayout(1, 0));
...
createAndShowGUI();
}
private static void createAndShowGUI() {
...
//Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo();
...
}
Do in this way
public SimpleTableDemo() {
super(new GridLayout(1, 0));
...
// pass the reference of this object
createAndShowGUI(this);
}
private static void createAndShowGUI(SimpleTableDemo newContentPane ) {
...
//remove this line
//SimpleTableDemo newContentPane = new SimpleTableDemo();
...
}
Screenshot:
I want to calculate the height of a dialog that contain only a table depending on how many rows that table it has so I'm using the cross multiplication rule.For example i check initially that my table is well fitting into the dialog(Without space at the bottom) for some value and after that i use the cross multiplication rule because data are dynamic.But unfortunately this rule does not solve the problem.What's the best rule for fitting a dynamic table inside a dialog or a frame?
Here is my code
public class FlowLayoutChangingGap {
public static void main(String[] args) {
// just for testing perpose but data are getting from database and it's dynamic
Object[][] data = {
{"Kathy", "Smith", "Snowboarding", new Integer(5)},
{"John", "Doe", "Rowing", new Integer(3)},
{"Sue", "Black", "Knitting", new Integer(2)},
{"Jane", "White", "Speed reading", new Integer(20)},
{"Joe", "Brown", "Pool", new Integer(10)}};
Object[] columnNames = {"firstname", "lastname", "age"};
final JTable table = new JTable(data, columnNames);
JFrame aWindow = new JFrame("This is a Test");
aWindow.setBounds(50, 50, 500, 500);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flow = new FlowLayout(FlowLayout.LEFT, 20, 30);
Container content = aWindow.getContentPane();
content.setLayout(flow);
JButton jButton = new JButton("Press Me");
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JPanel jPanel = new JPanel();
jPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
jPanel.add(table, gbc);
JDialog jdialog = new JDialog();
jdialog.setContentPane(jPanel);
jdialog.setLocationRelativeTo(null);
int height = table.getModel().getRowCount() * 25;
jdialog.setSize(400, height);
jdialog.setVisible(true);
}
};
jButton.addActionListener(l);
content.add(jButton);
aWindow.setVisible(true);
}
}
Here is a way to fix the number of rows displayed in the scroll-pane.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
class FlowLayoutChangingGap {
public static final int ROWS = 3;
FlowLayoutChangingGap() {
// just for testing perpose but data are getting from database and it's dynamic
Object[][] data = {
{"Kathy", "Smith", "Snowboarding", new Integer(5)},
{"John", "Doe", "Rowing", new Integer(3)},
{"Sue", "Black", "Knitting", new Integer(2)},
{"Jane", "White", "Speed reading", new Integer(20)},
{"Joe", "Brown", "Pool", new Integer(10)}};
Object[] columnNames = {"firstname", "lastname", "age"};
final JTable table = new JTable(data, columnNames) {
#Override
public Dimension getPreferredScrollableViewportSize() {
Dimension d = getPreferredSize();
// Note: margin is included in rowHeight
int n = getRowHeight(); // + getRowMargin();
// tbd: insets? we are one-off here
return new Dimension(d.width, (n * ROWS));
}
};
JPanel jPanel = new JPanel();
jPanel.setBorder(new EmptyBorder(6, 6, 6, 6));
jPanel.setLayout(new GridLayout());
JScrollPane sp = new JScrollPane(table);
//sp.getViewport().
jPanel.add(sp);
JDialog jdialog = new JDialog();
jdialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jdialog.setContentPane(jPanel);
jdialog.setLocationRelativeTo(null);
jdialog.pack();
jdialog.setVisible(true);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
new FlowLayoutChangingGap();
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}
I have this JPanel called CatalogPane, which is of size 800 by 600, which is inside a JTabbedPane inside a JFrame called BookFrame. So inside the CatalogPane, I created a JPanel called bookDisplay which displays a list of books and their details. I want it to be of size 780 by 900, leaving 20px for the scrollbar and taller than the frame so that it can scroll. Then I created a panel of size 800 by 400 because I need to leave some extra space at the bottom for other fields. I tried creating a JScrollPane for bookDisplay and then put it inside the other panel, but somehow the scrollbar appears but can't be used to scroll. I've experimented changing the sizes and scrollpane but I still can't get it to work.
What it looks like: http://prntscr.com/12j0d9
The scrollbar is there but can't work. I'm trying to get the scrollbar to work before I format the layout properly.
CatalogPane:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
public class CatalogPane extends JPanel{
//private Order currOrder = new Order();
//ArrayList<Book> bookCatalog = new ArrayList();
GridBagConstraints gbc = new GridBagConstraints();
GridBagLayout gbl = new GridBagLayout();
JPanel bookDisplay = new JPanel();
public CatalogPane()
{
//loadBookCatalog();
this.setPreferredSize(new Dimension(800, 600));
bookDisplay.setPreferredSize(new Dimension(780, 900));
bookDisplay.setLayout(new GridLayout(6, 5));
//bookDisplay.setLayout(gbl);
//gbc.fill = GridBagConstraints.NONE;
//gbc.weightx = 1;
//gbc.weighty = 1;
JLabel bookL = new JLabel("Books");
JLabel hardL = new JLabel("Hardcopy");
JLabel hardQuantL = new JLabel("Quantity");
JLabel eL = new JLabel("EBook");
JLabel eQuantL = new JLabel("Quantity");
bookDisplay.add(bookL);
bookDisplay.add(hardL);
bookDisplay.add(hardQuantL);
bookDisplay.add(eL);
bookDisplay.add(eQuantL);
/*
addComponent(bookL, 0, 0, 1, 1);
addComponent(hardL, 0, 1, 1, 1);
addComponent(hardQuantL, 0, 2, 1, 1);
addComponent(eL, 0, 3, 1, 1);
addComponent(eQuantL, 0, 4, 1, 1);
*/
Iterator<Book> bci = bookCatalog.iterator();
int row = 1;
/*
while(bci.hasNext())
{
Book temp = bci.next();
ImageIcon book1 = new ImageIcon(temp.getImage());
JLabel image = new JLabel(temp.getTitle(), book1, JLabel.CENTER);
image.setVerticalTextPosition(JLabel.TOP);
image.setHorizontalTextPosition(JLabel.CENTER);
String[] quant = {"1", "2", "3", "4", "5"};
JLabel hardP = new JLabel("$" + temp.getHardPrice());
JLabel eP = new JLabel("$" + temp.getEPrice());
JComboBox jbc1 = new JComboBox(quant);
JComboBox jbc2 = new JComboBox(quant);
jbc1.setSelectedIndex(0);
jbc2.setSelectedIndex(0);
/*
addComponent(b1temp, row, 0, 1, 1);
addComponent(hardP, row, 1, 1, 1);
addComponent(jbc1, row, 2, 1, 1);
addComponent(eP, row, 3, 1, 1);
addComponent(jbc2, row, 4, 1, 1);
row++;
bookDisplay.add(image);
bookDisplay.add(new JLabel("$" + temp.getHardPrice()));
bookDisplay.add(jbc1);
bookDisplay.add(new JLabel("$" + temp.getEPrice()));
bookDisplay.add(jbc2);
*/
for(int i=0;i<5;i++)
{
String[] quant = {"1", "2", "3", "4", "5"};
JComboBox jbc1 = new JComboBox(quant);
JComboBox jbc2 = new JComboBox(quant);
jbc1.setSelectedIndex(0);
jbc2.setSelectedIndex(0);
JLabel image = new JLabel("image");
bookDisplay.add(image);
bookDisplay.add(new JLabel("$" + 20));
bookDisplay.add(jbc1);
bookDisplay.add(new JLabel("$" + 15));
bookDisplay.add(jbc2);
}
JScrollPane vertical = new JScrollPane(bookDisplay);
//JPanel testP = new JPanel();
//testP.setPreferredSize(new Dimension(800, 400));
//JScrollPane vertical = new JScrollPane(testP);
//testP.add(bookDisplay);
vertical.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel testP = new JPanel();
testP.setPreferredSize(new Dimension(800, 400));
testP.add(vertical);
add(testP);
}
public void addComponent(Component c, int row, int col, int hei, int wid)
{
gbc.gridx = col;
gbc.gridy = row;
gbc.gridwidth = wid;
gbc.gridheight = hei;
gbl.setConstraints(c, gbc);
bookDisplay.add(c);
}
public Order getCurrOrder()
{
return currOrder;
}
private void loadBookCatalog()
{
try
{
String[] str = new String[8];
Scanner sc = new Scanner(new File("bookcat.txt"));
double temp1, temp2;
while(sc.hasNextLine())
{
str = sc.nextLine().split(";");
temp1 = Double.parseDouble(str[3]);
temp2 = Double.parseDouble(str[4]);
Book temp = new Book(temp1, temp2, str[0], str[1], str[2], str[5]);
bookCatalog.add(temp);
}
}
catch(IOException e)
{
System.out.println("File not found!");
}
}
}
BookFrame:
public class BookFrame extends JFrame{
JButton closeButton;
CatalogPane cp;
//IntroPane ip;
public BookFrame(String name)
{
super(name);
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(new IntroPane()),
"Thank you for visiting Groovy Book Company.", "Message",
JOptionPane.INFORMATION_MESSAGE, new ImageIcon("coffee.jpg"));
System.exit(0);
}
});
//ip = new IntroPane();
cp = new CatalogPane();
JTabbedPane jtp = new JTabbedPane();
jtp.setPreferredSize(new Dimension(800, 600));
//jtp.addTab("Intro", ip);
jtp.addTab("Catalog", cp);
add(jtp);
pack();
setVisible(true);
}
}
I'd look at JTable, which handles scrolling and rendering as shown here and below. This example shows how to render images and currency. Start by adding a third column for quantity of type Integer. This related example illustrates using a JComboBox editor.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.NumberFormat;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
/**
* #see https://stackoverflow.com/a/16264880/230513
*/
public class Test {
public static final Icon ICON = UIManager.getIcon("html.pendingImage");
private JPanel createPanel() {
JPanel panel = new JPanel();
DefaultTableModel model = new DefaultTableModel() {
#Override
public Class<?> getColumnClass(int col) {
if (col == 0) {
return Icon.class;
} else {
return Double.class;
}
}
};
model.setColumnIdentifiers(new Object[]{"Book", "Cost"});
for (int i = 0; i < 42; i++) {
model.addRow(new Object[]{ICON, Double.valueOf(i)});
}
JTable table = new JTable(model);
table.setDefaultRenderer(Double.class, new DefaultTableCellRenderer() {
#Override
protected void setValue(Object value) {
NumberFormat format = NumberFormat.getCurrencyInstance();
setText((value == null) ? "" : format.format(value));
}
});
table.setRowHeight(ICON.getIconHeight());
panel.add(new JScrollPane(table) {
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
});
return panel;
}
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane jtp = new JTabbedPane();
jtp.addTab("Test1", createPanel());
jtp.addTab("Test2", createPanel());
f.add(jtp);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}