Like the title said, the hearder name is just not showing up. i tried many options like using a JScrollPane. and fallowed many guide on this forum but no help. I really wanted to get resolve problem by myself but i have tried everything and out of option.
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.ScrollPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.awt.event.ActionEvent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;
public class Adminpage extends JPanel {
private JFrame frame;
static String ID[]={"name","Username","Password"};
static DefaultTableModel model;
private JTextField NametextField;
private JTextField UsertextField;
private JTextField PasstextField;
private JTable table;
private JScrollPane scroll;
/**
* Create the panel.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 497, 545);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JLabel lblAdminstratorPortal = new JLabel("Adminstrator Portal");
lblAdminstratorPortal.setFont(new Font("Tahoma", Font.BOLD, 20));
lblAdminstratorPortal.setBounds(109, 26, 218, 25);
frame.getContentPane().add(lblAdminstratorPortal);
JButton btnNewButton = new JButton("Add Librarian");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//model= (DefaultTableModel)table.getModel();
//model.addColumn("name");
//model.addColumn("Username");
//model.addColumn("Password");
model.addRow(new Object[]{NametextField.getText(),UsertextField.getText(),PasstextField.getText()});
}
});
btnNewButton.setBounds(10, 62, 108, 35);
frame.getContentPane().add(btnNewButton);
JButton btnDelete = new JButton("Delete");
btnDelete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
btnDelete.setBounds(130, 62, 108, 35);
frame.getContentPane().add(btnDelete);
JButton btnViewLibrarian = new JButton("View Librarian");
btnViewLibrarian.setBounds(245, 62, 108, 35);
frame.getContentPane().add(btnViewLibrarian);
JButton btnLogout = new JButton("Logout");
btnLogout.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
frame.dispose();
}
});
btnLogout.setBounds(363, 62, 108, 35);
frame.getContentPane().add(btnLogout);
//model= (DefaultTableModel)table.getModel();
JLabel lblName = new JLabel("Name");
lblName.setBounds(21, 144, 60, 14);
frame.getContentPane().add(lblName);
JLabel lblUsername = new JLabel("Username");
lblUsername.setBounds(21, 195, 60, 14);
frame.getContentPane().add(lblUsername);
JLabel lblPassword = new JLabel("Password");
lblPassword.setBounds(21, 250, 60, 14);
frame.getContentPane().add(lblPassword);
NametextField = new JTextField();
NametextField.setBounds(119, 141, 119, 20);
frame.getContentPane().add(NametextField);
NametextField.setColumns(10);
UsertextField = new JTextField();
UsertextField.setColumns(10);
UsertextField.setBounds(119, 192, 119, 20);
frame.getContentPane().add(UsertextField);
PasstextField = new JTextField();
PasstextField.setColumns(10);
PasstextField.setBounds(119, 247, 119, 20);
frame.getContentPane().add(PasstextField);
table = new JTable();
table.setBounds(10, 304, 461, 189);
frame.getContentPane().add(table);
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Adminpage() {
database();
setLayout(null);
initialize();
model= (DefaultTableModel)table.getModel();
model.addColumn("name");
model.addColumn("Username");
model.addColumn("Password");
}
public void database(){
try {
Class.forName("sun.jdbc.odbc.JdbsOdbcDriver");
Connection con = DriverManager.getConnection("jdbc:odbc:Games");
Statement st = con.createStatement();
String getquery = ("Select* from Games");
ResultSet rs= st.executeQuery(getquery);
while(rs.next()){
System.out.println(rs.getString(2));
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
You're adding the JTable directly to the GUI. Instead, yes you need to embed the JTable into the viewport of a JScrollPane and then add the JScrollPane to the GUI.
For example:
table = new JTable();
JScrollPane scrollPane = new JScrollPane(table);
// table.setBounds(10, 304, 461, 189);
scrollPane.setBounds(10, 304, 461, 189); // This is bad, but will leave for now
// frame.getContentPane().add(table);
frame.getContentPane().add(scrollPane);
Also, you're harming your GUI by using null layouts and absolute positioning, as this can interfere with a component's ability to show itself fully and correctly, to achieve its own preferred size. Much better is to learn and use the layout managers.
For instance, when I run your program on my platform, I see:
Note how the buttons do not show their full texts due to their not being allowed to achieve their preferred sizes.
For example, using BoxLayout with some nested JPanels, one using GridLayout(1, 0, 5, 0) for one row, variable number of columns, and a 5 point horizontal gap between components, and another nested JPanel using GridBagLayout, for placement of JTextFields and JLabels, and some "wrapper" JPanels using default FlowLayout to center components within them...
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class AdminPage2 extends JPanel {
private static final long serialVersionUID = 1L;
public static final String TITLE = "Administrator Portal";
private static final Font TITLE_FONT = new Font("Tahoma", Font.BOLD, 20);
private static final String[] COL_NAMES = {"Name", "User Name", "Password"};
private int txtFieldCols = 20;
private JTextField nameField = new JTextField(txtFieldCols);
private JTextField userNameField = new JTextField(txtFieldCols);
private JPasswordField passwordField = new JPasswordField(txtFieldCols);
private DefaultTableModel tableModel = new DefaultTableModel(COL_NAMES, 0);
private JTable table = new JTable(tableModel);
private JScrollPane tableScrollPane = new JScrollPane(table);
public AdminPage2() {
JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
titleLabel.setFont(TITLE_FONT);
JPanel titlePanel = new JPanel();
titlePanel.add(titleLabel);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
// of course you'd add ActionListeners or Actions to your buttons
buttonPanel.add(new JButton("Add Library"));
buttonPanel.add(new JButton("Delete"));
buttonPanel.add(new JButton("View Library"));
buttonPanel.add(new JButton("Logout"));
JPanel textFieldPanel = new JPanel(new GridBagLayout());
textFieldPanel.add(new JLabel("Name:"), createGbc(0, 0));
textFieldPanel.add(nameField, createGbc(1, 0));
textFieldPanel.add(new JLabel("User Name:"), createGbc(0, 1));
textFieldPanel.add(userNameField, createGbc(1, 1));
textFieldPanel.add(new JLabel("Password:"), createGbc(0, 2));
textFieldPanel.add(passwordField, createGbc(1, 2));
JPanel wrapTfPanel = new JPanel();
wrapTfPanel.add(textFieldPanel);
Dimension scrollPanePrefSz = tableScrollPane.getPreferredSize();
int w = scrollPanePrefSz.width;
int h = scrollPanePrefSz.height / 2;
scrollPanePrefSz = new Dimension(w, h);
tableScrollPane.setPreferredSize(scrollPanePrefSz);
// put together main JPanel components
int ebGap = 4;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(Box.createVerticalStrut(5));
add(titlePanel);
add(Box.createVerticalStrut(5));
add(buttonPanel);
add(Box.createVerticalStrut(5));
add(wrapTfPanel);
add(Box.createVerticalStrut(5));
add(tableScrollPane);
}
// create constraints to use when adding component to GridBagLayout
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
int in = 10;
int leftIn = x == 0 ? 4 * in : in;
gbc.insets = new Insets(in, leftIn, in, in);
return gbc;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
AdminPage2 mainPanel = new AdminPage2();
JFrame frame = new JFrame("Administrator Page");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Which displays as:
Regarding your questions:
but new question why give the scrollpane a bound instead of the table itself
The JScrollPane holds the JTable within it, and so if you use null layouts (which you shouldn't), and you're adding this JTable-containing JScrollPane to the GUI, you must set its bounds. Much better though is to use layout managers as I've outlined above. It makes it much easier to modify the GUI later and to debug it now.
and why adding the scrollpane into the panel instead of the table.
Because that's how JScrollPanes work. They don't add scrollbars to a component but rather nest the component itself, here the JTable, within the JScrollPane's viewport. Please read the JScrollPane Tutorial (see link) to see the details on this.
A further note on the power of layout managers. Say you want to add a new JLabel / JTextField combination, one that accepts a password hint, and say the JTextField's name is passwordHint. If you were using null layouts and absolute positioning, you'd have to set the bounds of your new JLabel and JTextField, but you'd also have to change the bounds of all components below and to the right of it, and would have to re-set the size of the GUI manually. If your GUI is very complex, this can lead to bugs and a lot of frustration.
If you used the layout managers above however, all you'd need to do would be to add two lines of code to the textFieldPanel JPanel creational code as shown below with the obvious comments:
// original textFieldPanel creational code
JPanel textFieldPanel = new JPanel(new GridBagLayout());
textFieldPanel.add(new JLabel("Name:"), createGbc(0, 0));
textFieldPanel.add(nameField, createGbc(1, 0));
textFieldPanel.add(new JLabel("User Name:"), createGbc(0, 1));
textFieldPanel.add(userNameField, createGbc(1, 1));
textFieldPanel.add(new JLabel("Password:"), createGbc(0, 2));
textFieldPanel.add(passwordField, createGbc(1, 2));
// !! ****** these lines added ******
textFieldPanel.add(new JLabel("Password Hint:"), createGbc(0, 3));
textFieldPanel.add(passwordHint, createGbc(1, 3));
This results in a perfect placement of the new components without adversely affecting the old:
Related
I currently have a jpanel with layout set to GridBagLayout, with gbc = new GridBagConstraints();, However for whatever value of x, y or gridwidth,gridheight the items don't move at all.
I would greatly appreciate an expert eye to look over my code to see what I am missing, Thanks in advance.
Edit: Added the imports and the main method
Edit 2: turns out I was thinking the x and y values were pixels and that was the reason it wasn't working
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class HomeScreenUI {
public void addobjects(Component componente, Container yourcontainer, GridBagLayout layout, GridBagConstraints gbc, int gridx, int gridy, int gridwidth, int gridheight){
gbc.gridx = gridx;
gbc.gridy = gridy;
gbc.gridwidth = gridwidth;
gbc.gridheight = gridheight;
layout.setConstraints(componente, gbc);
yourcontainer.add(componente);
}
HomeScreenUI(){
//frame
JFrame frame = new JFrame("Opisa");
//panels, one before button click and one after
JPanel panel = new JPanel();
JPanel panelAfterButtonClick = new JPanel();
GridBagLayout ourlayout;
ourlayout = new GridBagLayout();
panel.setLayout(ourlayout);
panelAfterButtonClick.setLayout(ourlayout);
GridBagConstraints gbc = new GridBagConstraints();
//jlabel that isnt displaying + dimensions
JLabel label = new JLabel("Opisa");
label.setFont(new Font("Helvetica", Font.PLAIN, 70));
//second jlabel that isn't displaying
JLabel label2 = new JLabel("Home");
label2.setFont(new Font("Helvetica", Font.PLAIN, 70));
//adding the labels to the panels
panel.add(label);
panelAfterButtonClick.add(label2);
//button that is displaying both before and after
JButton button = new JButton("Click Me..");
JButton buttonAfterClick = new JButton("Clicked Me..");
//adding the buttons to the jpanel
this.addobjects(label, panel, ourlayout, gbc, 0,0, 3, 1);
this.addobjects(button, panel, ourlayout, gbc, 700, 100, 2, 0);
this.addobjects(label2, panelAfterButtonClick, ourlayout, gbc, 200, 200, 1, 1);
this.addobjects(buttonAfterClick, panelAfterButtonClick, ourlayout, gbc, 700, 10, 2, 0);
//function that changes the panel after the button is clicked
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
frame.setContentPane(panelAfterButtonClick);
frame.invalidate();
frame.validate();
}
});
//adding the panel to the frame and setting the size
frame.add(panel);
frame.setSize(720,1280);
frame.setVisible(true);
}
}
public static void main (String args[]) {
HomeScreenUI hs = new HomeScreenUI();
}
It seems you are using GridBagLayout completely different than it was designed for.
Note you have one instance of GridBagLayout but want to use it for two panels. Each panel needs to have it's own LayoutManager instance.
Then look how many GridBagConstraints you have. Each Component that shall be added needs it's own instance to be properly managed.
Then there are strange values you are passing into GridBagConstraints. I suggest you take the time and go through How to Use GridBagLayout.
I modified your code to create the following GUI.
Here's what it looks like after you left-click the button.
You can swap back and forth between the two panels.
Here are the major changes I made to your code.
Code should be organized like an essay. The most important code should come first, followed by the less important code.
Break your code up into methods and classes. Each method should do one thing and do it well. This is called separation of concerns and it helps you to focus on one part of your code at a time.
To start the Swing application, I made a call to the SwingUtilities invokeLater method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.
The JFrame code is in the class constructor. The JFrame code has to be called in a certain order. This is the order I use for most of my Swing applications. Don't forget to call the setDefaultCloseOperation method. The JFrame.EXIT_ON_CLOSE parameter exits the application when you close the JFrame.
I used a CardLayout to hold the two subordinate JPanels. I created the CardLayout in its own method.
I created each subordinate JPanel in its own method. I used a GridBagLayout for both subordinate JPanels. As you can see in the code, you have to set quite a few GridBagConstraints parameters.
I created an anonymous ActionListener for each of the JButtons. The ActionListeners swap the two subordinate JPanels in the CardLayout.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
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.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class HomeScreenUI {
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new HomeScreenUI();
}
});
}
private CardLayout cardLayout;
private JPanel cardPanel;
public HomeScreenUI() {
JFrame frame = new JFrame("Opisa");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.cardPanel = createCardPanel();
frame.add(cardPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createCardPanel() {
cardLayout = new CardLayout();
JPanel panel = new JPanel(cardLayout);
panel.add(createOpisaPanel(), "Opisa");
panel.add(createHomePanel(), "Home");
return panel;
}
private JPanel createOpisaPanel() {
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.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
// jlabel that isnt displaying + dimensions
JLabel label = new JLabel("Opisa");
label.setFont(new Font("Helvetica", Font.PLAIN, 72));
panel.add(label, gbc);
gbc.gridy++;
JButton button = new JButton("Click Me..");
// function that changes the panel after the button is clicked
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
cardLayout.show(cardPanel, "Home");
}
});
panel.add(button, gbc);
return panel;
}
private JPanel createHomePanel() {
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.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
// second jlabel that isn't displaying
JLabel label2 = new JLabel("Home");
label2.setFont(new Font("Helvetica", Font.PLAIN, 72));
panel.add(label2, gbc);
gbc.gridy++;
JButton buttonAfterClick = new JButton("Clicked Me..");
buttonAfterClick.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
cardLayout.show(cardPanel, "Opisa");
}
});
panel.add(buttonAfterClick, gbc);
return panel;
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI_Borrower extends JFrame implements ActionListener {
JPanel panel = new JPanel();
JLabel lblName = new JLabel("Name:");
JLabel lblProg = new JLabel("Program:");
JLabel lblId = new JLabel("Library ID: ");
JLabel lblTitle = new JLabel("Add Borrower");
JTextField txtName = new JTextField(10);
JTextField txtProg = new JTextField(10);
JTextField txtId = new JTextField(10);
static int counter = 19000;
JButton btnSubmit = new JButton("Submit");
public GUI_Borrower() {
super("Add Borrower");
makeFrame();
showFrame();
}
public void makeFrame() {
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
add(lblTitle);
add(lblName);
add(txtName);
add(lblProg);
add(txtProg);
add(lblId);
add(txtId);
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(btnSubmit);
btnSubmit.addActionListener(this);
}
public void showFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 200);
setLocationRelativeTo(null);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (ae.getActionCommand().equals("Confirm")) {
txtName.setText("");
txtProg.setText("");
btnSubmit.setText("Submit");
} else if (source == btnSubmit) {
if (txtName.getText().equals("") && txtProg.getText().equals("")) {
txtId.setText("No entry of both");
} else if (txtName.getText().equals("")) {
txtId.setText("No entry of Name");
} else if (txtProg.getText().equals("")) {
txtId.setText("No entry of Program");
} else {
counter++;
txtId.setText("" + counter);
btnSubmit.setText("Confirm");
}
}
}
public static void main(String[] args) {
new GUI_Borrower();
}
}
I tried adding BoxLayout because all the text fields and labels are on one line. So I tried box Layout and failed.
Can anyone show me how to make it like the title one line, label Different line, button different line?
Like this:
As camickr says in his comment, you generally use a GridBagLayout to create a form.
I reworked your code because I hope to show a better way to code a GUI panel.
Here's the GUI.
The major changes I made include:
All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.
I organized the GUI code into three methods so I could focus on one part of the GUI at a time. The JFrame is created in the run method. The title JPanel is created in the createTitlePanel method. The form JPanel is created in the createFormPanel method. The code for the JFrame will rarely change from Swing application to Swing application.
I use Swing components. I don't extend Swing components, or any Java class, unless I intend to override one of the class methods.
The createFormPanel class uses the GridBagLayout to organize the labels and text fields in columns. You can think of the GridBagLayout as a flexible grid. The cells of the grid don't have to be the same size. The Oracle tutorial, How to Use GridBagLayout, has another example.
I put the ActionListener in a separate class. I made it an inner class in this example so I could paste the code as one file. Generally, you should put separate classes in separate files. It makes each class shorter and easier to understand.
Here's the runnable, example code.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
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.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class BorrowerGUI implements Runnable {
private static int ID_COUNTER = 19000;
public static void main(String[] args) {
SwingUtilities.invokeLater(new BorrowerGUI());
}
private JButton btnSubmit;
private JTextField txtName;
private JTextField txtProg;
private JTextField txtId;
#Override
public void run() {
JFrame frame = new JFrame("Add Borrower");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTitlePanel(), BorderLayout.BEFORE_FIRST_LINE);
frame.add(createFormPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTitlePanel() {
JPanel panel = new JPanel(new FlowLayout());
JLabel lblTitle = new JLabel("Add Borrower");
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
panel.add(lblTitle);
return panel;
}
private JPanel createFormPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel lblName = new JLabel("Name:");
panel.add(lblName, gbc);
gbc.gridx++;
txtName = new JTextField(20);
panel.add(txtName, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel lblProg = new JLabel("Program:");
panel.add(lblProg, gbc);
gbc.gridx++;
txtProg = new JTextField(20);
panel.add(txtProg, gbc);
gbc.gridx = 0;
gbc.gridy++;
JLabel lblId = new JLabel("Library ID:");
panel.add(lblId, gbc);
gbc.gridx++;
txtId = new JTextField(20);
txtId.setEditable(false);
panel.add(txtId, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.gridwidth = 2;
btnSubmit = new JButton("Submit");
btnSubmit.addActionListener(new SubmitListener());
panel.add(btnSubmit, gbc);
return panel;
}
public class SubmitListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
Object source = ae.getSource();
if (ae.getActionCommand().equals("Confirm")) {
txtName.setText("");
txtName.requestFocus();
txtProg.setText("");
txtId.setText("");
btnSubmit.setText("Submit");
} else if (source == btnSubmit) {
if (txtName.getText().equals("") &&
txtProg.getText().equals("")) {
txtId.setText("No entry of both");
} else if (txtName.getText().equals("")) {
txtId.setText("No entry of Name");
} else if (txtProg.getText().equals("")) {
txtId.setText("No entry of Program");
} else {
ID_COUNTER++;
txtId.setText("" + ID_COUNTER);
btnSubmit.setText("Confirm");
}
}
}
}
}
Edited to add: If you want the title JLabel to be right-justified, you'll have to switch to a BorderLayout. I added an empty border so the text wouldn't be on the right edge of the JFrame.
Here's the changed method.
private JPanel createTitlePanel(String title) {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
JLabel lblTitle = new JLabel(title);
lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
lblTitle.setForeground(Color.BLUE);
panel.add(lblTitle, BorderLayout.AFTER_LINE_ENDS);
return panel;
}
I'm a little lost here, when I run the program the buttons are in the middle of the input and not directly on the bottom aligned with it. I'm not sure what I'm doing wrong. I'm also trying to find out how to get statistics for my input like min and max value, and average word size. I'm a little lost, thanks!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.util.Arrays;
public class CopyTextPanel extends JPanel
{
private JTextField input;
private JLabel output, inlabel, outlabel;
private JButton compute, clear;
private JPanel panel, panel1, panel2;
public CopyTextPanel()
{
setLayout (new BoxLayout(this, BoxLayout.Y_AXIS));
inlabel = new JLabel("Input: ");
outlabel = new JLabel("Text Statistics Result: ");
input = new JTextField (50);
output = new JLabel();
compute = new JButton("Compute Statistics");
compute.addActionListener (new ButtonListener());
clear = new JButton("Clear Text");
clear.addActionListener (new ButtonListener());
panel = new JPanel();
panel1 = new JPanel();
panel2 = new JPanel();
output.setMaximumSize (new Dimension(500, 30));
output.setMinimumSize (new Dimension(500, 30));
panel.setMaximumSize (new Dimension(500, 30));
panel.setMinimumSize (new Dimension(500, 30));
panel.setBackground(Color.gray);
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(inlabel);
panel.add(input);
panel1.setLayout(new BoxLayout(panel1, BoxLayout.X_AXIS));
panel1.add(compute);
panel1.add(clear);
add (Box.createRigidArea (new Dimension(0, 10)));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.X_AXIS));
panel2.add(outlabel);
panel2.add(output);
setMaximumSize (new Dimension(600, 250));
setMinimumSize (new Dimension(600, 250));
setBackground(Color.white);
add (panel);
add (panel1);
add (panel2);
}
private class ButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent event)
{
String inputText = input.getText();//sets what is typed by the user
to a String object
String[] splitted = inputText.trim().split("\\p{javaSpaceChar}
{1,}");//makes a String array, and trims all the whitespaces from the user
input
int numberofWords = splitted.length;//it then sets splitted length
to an integer
String numow = Integer.toString(numberofWords);// finally it makes
the numberofwords int into a string
Arrays.sort(splitted);
if (event.getSource()==compute)//if the user presses the compute
button
{
output.setText (numow + " words; " );//the output is the string
of integers of how many words were typed
}
else//if the user presses another button
input.setText(" "); // clear text filed after copying
}
}
}
So based on the desired result...
I would recommend considering using a series of panels, dedicated to generating the layout requirements for each row, then wrapping those together into a single container.
For my money, GridBagLayout presents the most flexible option, while also presenting one of the more complicated at the same time.
This example focuses solely on the layout requirements, you'll have to figure out how to apply the functionality to it later.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Test");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() throws HeadlessException {
setBorder(new EmptyBorder(5, 5, 5, 5));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
JPanel fieldPane = new JPanel(new GridBagLayout());
JTextField inputField = new JTextField("Computer Science 1");
fieldPane.add(new JLabel("Input Text:"), gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
fieldPane.add(inputField, gbc);
JPanel buttonPane = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
buttonPane.add(new JButton("Computer Statistics"), gbc);
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 1;
buttonPane.add(new JButton("Clear Text"), gbc);
JPanel resultsPane = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
resultsPane.add(new JLabel("Text Statistics Result:"));
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 1;
resultsPane.add(new JLabel("3 words"), gbc);
gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(fieldPane, gbc);
add(buttonPane, gbc);
add(resultsPane, gbc);
}
}
}
I strongly recommend having a look at Laying Out Components Within a Container for more details about how various layout managers work
You should use Layouts such as BorderLayout that might help you.
Change the JPanels by doing panel.add(new JButton("East"),BorderLayout.EAST);
etc.. I hope it helps. If you dont use layouts they will end up randomized.
So I'm trying to copy the layout of this website.
Website Pinterest Log In
Here's some what I have already done.
I'm using "null" for my layout.
I also put an actionlistener on my button which shows another frame.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Frame {
public static void main (String [] args) {
JFrame frame = new JFrame("Pinterest");
frame.setVisible(true);
frame.setSize(1300,750);
JPanel panel = new JPanel();
frame.add(panel);
JLabel name = new JLabel("Log in to Pinterest");
name.setBounds(500, 96, 300, 100);
name.setFont(new Font("Tahoma", Font.PLAIN, 28));
JTextField text1 = new JTextField(15);
text1.setBounds(500, 450, 300, 40);
JTextField text2 = new JTextField(15);
text2.setBounds(500, 350, 300, 40);
JButton button = new JButton("Log In");
button.setBounds(560,550, 200,30 );
panel.setLayout(null);
panel.add(name);
panel.add(text1);
panel.add(text2);
panel.add(button);
button.addActionListener(new Action1());
}
static class Action1 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JFrame frame2= new JFrame("Pinterest");
frame2.setVisible(true);
frame2.setSize(1300,750);
}}
Every time I would run this in my JCreator it would only show my frame. Then I have to maximize it to view the components but after I maximize it then minimize it doesn't hide anymore.
After I maximize the frame.
What is wrong with my code?
Does my code works on yours smoothly? does it shows?
How can I hide the first frame after clicking the button?
I'm having a hard time putting icon on the frame too.
Thanks for the help.
There are a number of basic mistakes
null layouts. Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
Making the frame visible before you've finished updating the UI. In most cases this can be fixed with revalidate, but since that causes the layout managers to recalculate their layouts, it's pointless when you're using null layouts
The simple answer is, use layout managers. The longer answer is more complicated.
You have three distinct areas, the "login with" group, the "field" group and (what I like to term) the "action" group. Each of these have there own requirements and functionality, it's best to try a seperate them if you can.
This will allow to apply functionality to each group or class which is unique to that group/class and reduce a lot of management head aches
The following examples focus on the layout, it does not focus on how you would then connect the functionality, this would be achieved simply through the use of an Observer Pattern, perhaps like ActionListener
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 LoginPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LoginPane extends JPanel {
public LoginPane() {
setBackground(Color.WHITE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(4, 20, 4, 20);
JLabel title = new JLabel("Log in to Pinterest");
title.setFont(title.getFont().deriveFont(Font.BOLD, 18f));
title.setBorder(new EmptyBorder(10, 0, 10, 0));
add(title, gbc);
add(new GroupPane(), gbc);
gbc.insets = new Insets(4, 0, 4, 0);
add(new JSeparator(JSeparator.HORIZONTAL), gbc);
gbc.insets = new Insets(4, 20, 4, 20);
add(new FieldPane(), gbc);
gbc.insets = new Insets(4, 0, 0, 0);
add(new ActionPane(), gbc);
}
}
public class GroupPane extends JPanel {
public GroupPane() {
setOpaque(false);
JPanel fbPane = new JPanel();
JPanel goPane = new JPanel();
JPanel twPane = new JPanel();
fbPane.setBackground(Color.RED);
goPane.setBackground(Color.BLUE);
twPane.setBackground(Color.CYAN);
fbPane.add(makeLabel("Log in with Facebook"));
goPane.add(makeLabel("Log in with Google"));
twPane.add(makeLabel("Log in with Twitter"));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(4, 0, 4, 0);
add(fbPane, gbc);
add(goPane, gbc);
add(twPane, gbc);
}
protected JLabel makeLabel(String text) {
JLabel label = new JLabel(text);
label.setForeground(Color.WHITE);
label.setFont(label.getFont().deriveFont(Font.BOLD, 14f));
return label;
}
}
public class FieldPane extends JPanel {
private JTextField email;
private JPasswordField password;
public FieldPane() {
setOpaque(false);
email = new JTextField(10);
password = new JPasswordField(10);
email.setBackground(new Color(225, 225, 225));
password.setBackground(new Color(225, 225, 225));
Font font = email.getFont().deriveFont(Font.PLAIN, 24f);
email.setFont(font);
password.setFont(font);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(4, 0, 4, 0);
add(email, gbc);
add(password, gbc);
JLabel label = new JLabel("Are you a business? Get started here");
label.setFont(label.getFont().deriveFont(Font.PLAIN, 10f));
gbc.insets.left = 4;
add(label, gbc);
}
}
public class ActionPane extends JPanel {
public ActionPane() {
setBorder(new EmptyBorder(10, 20, 10, 20));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.WEST;
add(makeLabel("Forgot your password?"), gbc);
gbc.gridy++;
add(makeLabel("Sign up now"), gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.gridheight = 2;
gbc.ipady = 10;
gbc.anchor = GridBagConstraints.EAST;
JButton login = new JButton("Log in");
add(login, gbc);
}
protected JLabel makeLabel(String text) {
JLabel label = new JLabel(text);
label.setForeground(Color.DARK_GRAY);
return label;
}
}
}
Take a look at Laying Out Components Within a Container and How to Use GridBagLayout. The LoginPane could also make use of a GridLayout, see for more details
For some reason my scrollbar is appearing but it is not working. What is suppose to happen is using the scrollbar to scroll through the text of the textarea. Can somebody please explain why this isnt working?
import java.io.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class App extends JFrame{
private JPanel paneel;
public App(){
paneel = new AppPaneel();
setContentPane(paneel);
}
public static void main(String args[]){
JFrame frame = new App();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setTitle("Auto Clicker");
frame.setVisible(true);
}
}
class AppPaneel extends JPanel{
private JTextField delayField, xLocation, yLocation;
private JTextArea listArea;
private JButton addButton, saveButton, runButton;
private JScrollPane scroll;
public AppPaneel(){
setLayout(null);
delayField = new JTextField();
delayField.setBounds(10, 10, 85, 25);
delayField.setText("delay in ms");
xLocation = new JTextField();
xLocation.setBounds(105, 10, 85, 25);
xLocation.setText("X position");
yLocation = new JTextField();
yLocation.setBounds(200, 10, 85, 25);
yLocation.setText("Y position");
addButton = new JButton("Add");
addButton.setBounds(295, 10, 75, 24);
addButton.addActionListener(new AddHandler());
listArea = new JTextArea();
listArea.setBounds(10, 45, 360, 180);
scroll = new JScrollPane(listArea);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scroll.setBounds(370, 45, 20, 180);
saveButton = new JButton("Save");
saveButton.setBounds(10, 230, 85, 24);
runButton = new JButton("Run (F1)");
runButton.setBounds(105, 230, 85, 24);
runButton.addActionListener(new RunHandler());
add(delayField);
add(xLocation);
add(yLocation);
add(addButton);
add(listArea);
add(saveButton);
add(runButton);
add(scroll);
}
class AddHandler implements ActionListener{
public void actionPerformed(ActionEvent a){
listArea.setText(listArea.getText() + delayField.getText() + ", " + xLocation.getText() + ", " + yLocation.getText() + ", " + "click;" + "\n");
}
}
class RunHandler implements ActionListener{
private Robot bot;
private String text;
int foo = Integer.parseInt("1234");
public void actionPerformed(ActionEvent b) {
try{
text = listArea.getText();
bot = new Robot();
for(String line : text.split("\\n")){
int delay = Integer.parseInt((line.substring(0, 4)));
int xpos = Integer.parseInt((line.substring(6, 10)));
int ypos = Integer.parseInt((line.substring(12, 16)));
bot.mouseMove(xpos, ypos);
Thread.sleep(delay);
bot.mousePress(InputEvent.BUTTON1_MASK);
bot.mouseRelease(InputEvent.BUTTON1_MASK);
}
}
catch (AWTException | InterruptedException e){
e.printStackTrace();
}
}
}
}
Don't use null layouts and setBounds as it is messing up your program. We tell folks time and time again not to do this for a reason -- by setting the JTextArea's bound you constrain its size so it won't grow when it needs to. The solution, as always -- learn and use the layout managers. Set the JTextArea's column and row properties but not its bounds, its size, or its preferred size.
Next don't do this: Thread.sleep(delay); in your Swing application as it will put the entire application to sleep. Use a Swing Timer instead for any delays. The tutorials can help you use this.
For a non-functional layout example:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;
#SuppressWarnings("serial")
public class App2 extends JPanel {
private static final int GAP = 5;
private JTextField textField1 = new JTextField(GAP);
private JTextField textField2 = new JTextField(GAP);
private JTextField textField3 = new JTextField(GAP);
private JTextArea textArea = new JTextArea(15, 30);
public App2() {
JPanel topPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
topPanel.add(textField1);
topPanel.add(textField2);
topPanel.add(textField3);
topPanel.add(new JButton("Add"));
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel bottomPanel = new JPanel(new GridLayout(1, 0, GAP, GAP));
bottomPanel.add(new JButton("Save"));
bottomPanel.add(new JButton("Run (F1)"));
bottomPanel.add(new JLabel(""));
bottomPanel.add(new JLabel(""));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
setLayout(new BorderLayout(GAP, GAP));
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Auto Clicker");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new App2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Your whole approach is wrong. You should not be using a null layout. For example:
scroll.setBounds(370, 45, 20, 180);
you are setting the width to 20. Well how to you expect the text area to display in 20 pixels? This is the problem with using setBounds(...), the random numbers you use have no meaning. Let a layout manager do its job. Also:
add(listArea);
The problem is that a component can only have a single parent. You originally created the JScrollPane with the text area which is correct.
But then you add the text area directly to the frame which removes it from the scroll pane so the scroll panel will no longer function.
Get rid of that statement and just add the scroll pane to the frame.
However, I don't recommend you use this as your final solution. I just wanted to mention the current problems so you hopefully understand the benefits of using layout managers and so that you don't try to share components again.
The proper solution is to use layout managers as has been suggested by the "Community Wiki". Then the layout manager will determine the size and location of each component so you don't need to worry about calculating your pixel values correctly.