which layout manager would be appropriate to my design? - java

I am a beginner to Java. I would like some help in Swings to position my components.
I am not able to decide as which layout manager should I use to position my components in the following order
+-----------------------------------+
| |
| Username Text Field |
| Password Password Field |
| |
| Submit button |
| |
+-----------------------------------+
The following is my code
package ssst;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
class Test implements ActionListener{
JButton submit;
JFrame j;
JFrame jf;
public Test()
{
j = new JFrame("PLAIN");
j.setBounds(500,150,300,400);
JPanel panel = new JPanel();
j.add(panel);
GridBagLayout gb = new GridBagLayout();
panel.setLayout(gb);
GridBagConstraints c = new GridBagConstraints();
JLabel label = new JLabel("User Name");
c.gridx=0;
c.gridy=0;
c.fill=GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.WEST;
c.ipadx=5;
c.ipady=5;
c.insets= new Insets(7,7,7,7);
panel.add(label,c);
JTextField username = new JTextField(10);
c.gridx=1;
c.gridy=0;
c.fill=GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.WEST;
c.ipadx=5;
c.insets= new Insets(7,7,7,7);
panel.add(username,c);
JLabel password= new JLabel("Password");
c.gridx=0;
c.gridy=1;
c.fill=GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.WEST;
c.ipadx=5;
c.insets= new Insets(7,7,7,7);
panel.add(password,c);
JPasswordField pass = new JPasswordField(10);
c.gridx=1;
c.gridy=1;
c.fill=GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.WEST;
c.insets= new Insets(7,7,7,7);
panel.add(pass,c);
submit = new JButton("Submit");
c.gridx=1;
c.gridy=6;
c.fill=GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.WEST;
c.insets= new Insets(7,7,7,7);
panel.add(submit,c);
submit.addActionListener(this);
j.setVisible(true);
j.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
j.setVisible(false);
jf = new JFrame("NEw Window");
jf.setVisible(true);
jf.setBounds(500,150,300,400);
JPanel panel2 = new JPanel();
panel2.setLayout(null);
jf.add(panel2);
JButton logout = new JButton("LOGOUT");
logout.setBounds(100, 30, 400, 30);
panel2.add(logout);
logout.addActionListener(new Test2());
jf.setDefaultCloseOperation(j.EXIT_ON_CLOSE);
}
class Test2 implements ActionListener{
public void actionPerformed(ActionEvent e) {
jf.dispose();
j.setVisible(true);
}
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new Test();
}
}
);
}
}

You could use a GridBagLayout and a JOptionPane
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class LoginPane extends JPanel {
private JTextField userName;
private JPasswordField password;
public LoginPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(4, 4, 4, 4);
add(new JLabel("Username:"), gbc);
gbc.gridy++;
add(new JLabel("Password:"), gbc);
userName = new JTextField(10);
password = new JPasswordField(10);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(userName, gbc);
gbc.gridy++;
add(password, gbc);
}
public String getUsername() {
return userName.getText();
}
public char[] getPassword() {
return password.getPassword();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
LoginPane loginPane = new LoginPane();
int option = JOptionPane.showOptionDialog(
null,
loginPane,
"Login",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE,
null,
new Object[]{"Submit"},
"Submit");
if (option == 0) {
System.out.println("Happy");
}
}
});
}
}
You could possibly use GridLayout with this concept as well.
Take a look at http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html for more ideas and links to other layout managers

go for GridBagLayout, logic of layout is simple. It works on X and Y co-ordinates.
here
Also you should go through other layout as well, it will help you decide in future designs.

Better to use GridBagLayout, in case if u add new components, Layout manager as to take care to fit the components with in the screen if u (maximized/Restore Down).

It is subjective to say what layout manager is appropriate for a
design. This design is a no-brainer for the MigLayout manager.
For a comparison, I provide a solution with a MigLayout.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutLoginEx extends JFrame {
public MigLayoutLoginEx() {
initUI();
setTitle("Log in");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
setLayout(new MigLayout("ins 15, wrap 2", "[][grow]"));
JLabel lbl1 = new JLabel("User name:");
JTextField field1 = new JTextField(10);
JLabel lbl2 = new JLabel("Password:");
JPasswordField field2 = new JPasswordField(10);
JButton btn = new JButton("Submit");
add(lbl1);
add(field1, "growx");
add(lbl2);
add(field2, "growx");
add(btn, "span 2, center, gaptop 20");
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutLoginEx ex = new MigLayoutLoginEx();
ex.setVisible(true);
}
});
}
}
The layout is achieved with six lines of layout code.

Related

How to set frame visibility conditionally in JSwing?

I'm trying to create a login panel in Java Swing where the user will first get a screen that requires them to enter the credentials and if they match the correct credentials, they will be directed to another java GUI class called UserManager. I'm not sure how I can set the current frame (of the login panel) to be false and the set the frame visible of the new panel that I want to switch to (the UserManger panel) to be true.
Here is what I have so far but it's not working:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import javax.swing.JButton;
public class Main implements ActionListener {
private static JLabel label;
private static JTextField userText;
private static JLabel passwordLabel;
private static JPasswordField passwordText;
private static JButton button;
private static JLabel success;
private static boolean loggedIn = false;
public static void main(String[] args) {
// JOptionPane.showMessageDialog(null, "Login");
JFrame f = new JFrame();
JPanel panel = new JPanel();
f.setSize(100, 100);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel);
panel.setLayout(null);
// username text label
label = new JLabel("User");
label.setBounds(10, 20, 80, 25);
panel.add(label);
userText = new JTextField(20);
userText.setBounds(100, 20, 165, 25);
panel.add(userText);
// pasword label
passwordLabel = new JLabel("Password");
passwordLabel.setBounds(10, 50, 80, 25);
panel.add(passwordLabel);
passwordText = new JPasswordField(20);
passwordText.setBounds(100, 50, 165, 25);
panel.add(passwordText);
button = new JButton("Login");
button.setBounds(10, 80, 80, 25);
button.addActionListener(new Main());
panel.add(button);
success = new JLabel("");
success.setBounds(10, 110, 300, 25);
panel.add(success);
f.setVisible(true);
if (loggedIn) {
UserManager frame = new UserManager();
f.setVisible(false);
frame.setVisible(true);
}
}
#Override
public void actionPerformed(ActionEvent e) {
String user = userText.getText();
String password = passwordText.getText();
System.out.println(user + ", " + password);
if(user.equals("John") && password.equals("hello")) {
success.setText("Login successful");
loggedIn = true;
}
else {
success.setText("Incorrect credentials.");
}
}
}
Use a CardLayout
See for How to Use CardLayout more details.
This will encourage you to isolate you functionality into individual components, there by isolating the workflows and supporting the "single responsibility" concept.
import java.awt.CardLayout;
import java.awt.EventQueue;
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.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
private UserPane userPane;
private LoginPane loginPane;
public MainPane() {
setLayout(new CardLayout());
userPane = new UserPane();
loginPane = new LoginPane(new AuthenticationListener() {
#Override
public void authenticationWasSuccessful(User user) {
userPane.setUser(user);
// The user pane's content size will have changed
SwingUtilities.windowForComponent(userPane).pack();
((CardLayout) getLayout()).show(MainPane.this, "USER");
}
#Override
public void authenticationDidFail() {
JOptionPane.showMessageDialog(MainPane.this, "Authentication failed", "Error", JOptionPane.ERROR_MESSAGE);
}
});
add(userPane, "USER");
add(loginPane, "LOGIN");
((CardLayout) getLayout()).show(this, "LOGIN");
}
}
public interface User {
public String getName();
}
public class DefaultUser implements User {
private String name;
public DefaultUser(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public interface AuthenticationListener {
public void authenticationWasSuccessful(User user);
public void authenticationDidFail();
}
public class LoginPane extends JPanel {
private JTextField user;
private JPasswordField password;
private JButton login;
private AuthenticationListener loginListener;
public LoginPane(AuthenticationListener listener) {
setBorder(new EmptyBorder(32, 32, 32, 32));
this.loginListener = listener;
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel("User name:"), gbc);
gbc.gridy++;
add(new JLabel("Password:"), gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
user = new JTextField(12);
password = new JPasswordField(12);
add(user, gbc);
gbc.gridy++;
add(password, gbc);
login = new JButton("Login");
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(login, gbc);
login.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean accept = (boolean) (((int) Math.round(Math.random() * 1)) == 0 ? true : false);
if (accept) {
loginListener.authenticationWasSuccessful(new DefaultUser(user.getText()));
} else {
loginListener.authenticationDidFail();
}
}
});
}
}
public class UserPane extends JPanel {
private JLabel userLabel;
public UserPane() {
JLabel label = new JLabel("Welcome!");
Font font = label.getFont();
label.setFont(font.deriveFont(Font.BOLD, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(label, gbc);
userLabel = new JLabel();
add(userLabel, gbc);
}
public void setUser(User user) {
userLabel.setText(user.getName());
}
}
}
Use a modal JDialog
See How to Make Dialogs for more details.
More windows isn't always a good choice, but in the context of gathering user credentials, I think you can make an argument.
This makes use of a modal dialog to stop the code execution at the point that the window is made visible and it won't continue until the window is closed. This allows you an opportunity to get and validate the user credentials before the code continues (it's black magic in how it works, but it's a very common workflow)
import java.awt.EventQueue;
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.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
User user = LoginPane.showLoginDialog();
if (user != null) {
JFrame frame = new JFrame();
frame.add(new UserPane(user));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} else {
// Well, you really don't know do you? Did they cancel
// the dialog or did authentication fail?
}
}
});
}
public interface User {
public String getName();
}
public static class DefaultUser implements User {
private String name;
public DefaultUser(String name) {
this.name = name;
}
#Override
public String getName() {
return name;
}
}
public static class LoginPane extends JPanel {
public interface AuthenticationListener {
public void authenticationWasSuccessful(User user);
public void authenticationDidFail();
}
private JTextField userTextField;
private JPasswordField passwordField;
private JButton loginButton;
private User user;
public LoginPane(AuthenticationListener listener) {
setBorder(new EmptyBorder(32, 32, 32, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel("User name:"), gbc);
gbc.gridy++;
add(new JLabel("Password:"), gbc);
gbc.gridx++;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
userTextField = new JTextField(12);
passwordField = new JPasswordField(12);
add(userTextField, gbc);
gbc.gridy++;
add(passwordField, gbc);
loginButton = new JButton("Login");
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(loginButton, gbc);
loginButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean accept = (boolean) (((int) Math.round(Math.random() * 1)) == 0 ? true : false);
if (accept) {
user = new DefaultUser(userTextField.getText());
listener.authenticationWasSuccessful(user);
} else {
user = null;
listener.authenticationDidFail();
}
}
});
}
public User getUser() {
return user;
}
public static User showLoginDialog() {
JDialog dialog = new JDialog();
dialog.setTitle("Login");
dialog.setModal(true);
LoginPane loginPane = new LoginPane(new LoginPane.AuthenticationListener() {
#Override
public void authenticationWasSuccessful(User user) {
dialog.dispose();
}
#Override
public void authenticationDidFail() {
JOptionPane.showMessageDialog(dialog, "Authentication failed", "Error", JOptionPane.ERROR_MESSAGE);
}
});
dialog.add(loginPane);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
return loginPane.getUser();
}
}
public class UserPane extends JPanel {
public UserPane(User user) {
setBorder(new EmptyBorder(32, 32, 32, 32));
JLabel label = new JLabel("Welcome!");
Font font = label.getFont();
label.setFont(font.deriveFont(Font.BOLD, 32));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(label, gbc);
JLabel userLabel = new JLabel();
userLabel.setText(user.getName());
add(userLabel, gbc);
}
}
}
You need to unset visibility of this frame and set visible User manager at the action performed level:
private navigateToNextFrame(){
f.dispose(false);
UserManager frame = new UserManager();
frame.setVisible(true);
}
Now you need to call this method in the action performed method instead of loggedin=true and delete block in main main method (if (loggedIn))
A little suggestion : User Manager could be a singleton so you can create it at least 1 time.

Java GUI layout cannot quite get it right

I tried a bunch of different layouts but none are giving me the desired effect.
I want something like this:
+-----------------------------+
Centered Text
+-------+
|Button |
+-------+
+-----------------------------+
In html it might look like this:
<p align="center">Some text</p>
<input type="button" value="Press"/>
The trouble I am having is with certain layouts (BorderLayout) it likes to resize the button to fit. Other layouts (Boxlayout and GroupLayout) will do something like this:
+-----------------------------+
Centered Text
+-------+
|Button |
+-------+
+-----------------------------+
Even when I have the JLabel aligned to CENTER and the Button aligned to LEFT.
Much appreciation to my helpers.
There are a number layouts that would be able to achieve this, in fact, you might even be able to use BorderLayout and FlowLayout together to do this, but this example simply uses GridBagLayout
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ExampleLayout {
public static void main(String[] args) {
new ExampleLayout();
}
public ExampleLayout() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
JLabel center = new JLabel("Centered Text");
center.setHorizontalAlignment(JLabel.CENTER);
add(center, gbc);
gbc.gridy++;
gbc.fill = GridBagConstraints.NONE;
gbc.gridwidth = 1;
gbc.weightx = 0;
gbc.anchor = GridBagConstraints.WEST;
JButton button = new JButton("Button");
add(button, gbc);
}
}
}
Take a look at Laying Out Components Within a Container for more examples and details
Although MadProgrammer and Costis Aivalis already answered your question, here is also an answer with MigLayout:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
public class MigLayoutDemo {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Centered text");
JButton button = new JButton("Button");
public MigLayoutDemo() {
panel.setLayout(new MigLayout());
label.setHorizontalAlignment(JLabel.CENTER);
panel.add(label, "wrap, pushx, growx");
panel.add(button);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(MigLayoutDemo::new);
}
}
Same effect, but this approach is less verbose unlike in case of GridBagLayout and I personally think that MigLayout is easier to use.
FlowLayout(int align) allows you to define justification. The default is CENTER. If you just left justify the FlowLayout of the panel that contains your button it works without having to use GridBagLayout manually. NetBeans provide an excellent GridBagLayout customizer, but you do not want to touch the code it generates automatically.
import javax.swing.*;
import java.awt.*;
public class MyLooks extends JFrame {
public MyLooks() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
p = new JPanel(new GridLayout(2, 1));
p1 = new JPanel();
p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
myLabel = new JLabel("this is a label");
myButton = new JButton("press");
p1.add(myLabel);
p2.add(myButton);
p.add(p1);
p.add(p2);
setContentPane(p);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MyLooks().setVisible(true);
}
});
}
private JLabel myLabel;
private JButton myButton;
private JPanel p, p1, p2;
}

How to set Text like Placeholder in JTextfield in swing

I want to put some texts in text-Field when the form is load which instruct to user and when user click on that text-filed the texts remove automatically.
txtEmailId = new JTextField();
txtEmailId.setText("Email ID");
i have wrote above code but it display the text and keep as it is when user click on that text button i want to remove it.
is there any way to do this task?
I use to override the text fields paint method, until I ended up with more custom text fields then I really wanted...
Then I found this prompt API which is simple to use and doesn't require you to extend any components. It also has a nice "buddy" API
This has now been included in the SwingLabs, SwingX library which makes it even eaiser to use...
For example (this uses SwingX-1.6.4)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.jdesktop.swingx.prompt.PromptSupport;
public class PromptExample {
public static void main(String[] args) {
new PromptExample();
}
public PromptExample() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTextField bunnies = new JTextField(10);
JTextField ponnies = new JTextField(10);
JTextField unicorns = new JTextField(10);
JTextField fairies = new JTextField(10);
PromptSupport.setPrompt("Bunnies", bunnies);
PromptSupport.setPrompt("Ponnies", ponnies);
PromptSupport.setPrompt("Unicorns", unicorns);
PromptSupport.setPrompt("Fairies", fairies);
PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, bunnies);
PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIGHLIGHT_PROMPT, ponnies);
PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.SHOW_PROMPT, unicorns);
PromptSupport.setFontStyle(Font.BOLD, bunnies);
PromptSupport.setFontStyle(Font.ITALIC, ponnies);
PromptSupport.setFontStyle(Font.ITALIC | Font.BOLD, unicorns);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(bunnies, gbc);
frame.add(ponnies, gbc);
frame.add(unicorns, gbc);
frame.add(fairies, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
JTextField busqueda = new JTextField(20);
add(busqueda);
busqueda.setHorizontalAlignment(SwingConstants.CENTER);
if (busqueda.getText().length() == 0) {
busqueda.setText("Buscar");
busqueda.setForeground(new Color(150, 150, 150));
}
busqueda.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
busqueda.setText("");
busqueda.setForeground(new Color(50, 50, 50));
}
#Override
public void focusLost(FocusEvent e) {
if (busqueda.getText().length() == 0) {
busqueda.setText("Buscar");
busqueda.setForeground(new Color(150, 150, 150));
}
}
});
You can download this NetBeans plugin which you can use to create a placeholder with just one line.

How to create snapped components with java swing?

I have worked hard on writing my GUI in swing however I am trying to improve it further since I feel it still looks a little off.
I would ideally like:
the button to snap to the top right,
the textfield to be the same height as the button and stretch from the top left to the button edge
the scrollpane to stretch from the bottom of the textfield and the button to the edges of the window even when stretched.
I'm unsure how to "snap" the components to the top right, top left and rest of the area respectively.
#SuppressWarnings("serial")
class TFrame extends JFrame
{
TFrame()
{
super("Huffman Compression");//setTitle
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setResizable(true);
jPanel = new JPanel();
jTextField = new JTextField("Enter string to compress...");
jButton = new JButton("Compress");
jButton.setFocusable(false);
jTextArea = new JTextArea("LOG AREA", 30, 30);
jTextArea.setWrapStyleWord(true);
jTextArea.setLineWrap(true);
jTextArea.setEditable(false);
jTextArea.setFocusable(false);
jTextArea.setOpaque(false);
jScrollPane = new JScrollPane(jTextArea);
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
jScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
jPanel.add(jTextField, BorderLayout.WEST);
jPanel.add(jButton, BorderLayout.EAST);
jPanel.add(jScrollPane, BorderLayout.SOUTH);
add(jPanel);
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException
| InstantiationException
| IllegalAccessException
| UnsupportedLookAndFeelException e)
{
e.printStackTrace();
}
setVisible(true);
}
private JPanel jPanel;
private JTextField jTextField;
private JButton jButton;
private JTextArea jTextArea;
private JScrollPane jScrollPane;
}
public static void main(String[] args)
{
TFrame frame = new TFrame();
frame.pack();
...
This is what it currently looks like:
http://i.imgur.com/90cmDl1.png
Regards.
Basically, you need to take advantage of a series of layout managers (commonly known as "compound layouts").
For example, you can accomplish the requirements for the button and field using a GridBagLayout and the by using a BorderLayout, you can accomplish the rest, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class BrowserWindow {
public static void main(String[] args) {
new BrowserWindow();
}
public BrowserWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JPanel topPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
topPane.add(new JTextField(10), gbc);
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx++;
topPane.add(new JButton("Compress"), gbc);
JTextArea ta = new JTextArea("Log...", 30, 30);
JScrollPane sp = new JScrollPane(ta);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(topPane, BorderLayout.NORTH);
frame.add(sp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Take a look at Laying Out Components Within a Container for more details

More than one JFrame

I currently have two frames, when you run the application the first JFrame that shows is a login, it has two input fields and a button. When the user logs in and is verified, I would like to close the frame and start up the second one.
So, the only thing I can think of doing is doing setVisible(false) for the login frame and setVisible(true) for the Main frame.
Is there a better way to do this, or is that the only way?
Personnally, I would start up your second JFrame immediately and replace your first frame with a modal JDialog which would be owned by the JFrame.
See also this answer to The Use of Multiple JFrames, Good/Bad Practice?
Here is a basic demo of what I suggest:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLogin {
private JFrame frame;
private boolean authenticated;
private JTextField login;
private JPasswordField password;
protected void initUI() {
frame = new JFrame(TestLogin.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setVisible(true);
}
protected void showLoginDialog() {
authenticated = false;
final JDialog dialog = new JDialog(frame, "Please provide your credentials");
dialog.setModal(true);
JPanel panel = new JPanel(new GridBagLayout());
JPanel buttonPanel = new JPanel();
login = new JTextField(40);
password = new JPasswordField(20);
JLabel loginLabel = new JLabel("Login:");
JLabel passwordLabel = new JLabel("Password:");
JButton ok = new JButton("OK");
ok.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Here perform authentication and set authentication flag to appropriate value
authenticated = true;
if (authenticated) {
setUpFrame();
dialog.dispose();
}
}
});
JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
dialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosed(WindowEvent e) {
if (!authenticated) {
System.exit(0);
}
}
});
dialog.getRootPane().setDefaultButton(ok);
buttonPanel.add(ok);
buttonPanel.add(cancel);
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 5, 5);
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(loginLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1.0;
panel.add(login, gbc);
gbc.gridwidth = 1;
gbc.weightx = 0;
panel.add(passwordLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1.0;
panel.add(password, gbc);
panel.add(buttonPanel, gbc);
dialog.add(panel);
dialog.pack();
dialog.setLocationRelativeTo(frame);
while (!authenticated) {
dialog.setVisible(true);
}
}
protected void setUpFrame() {
frame.add(new JLabel("Successfully authenticated"));
frame.revalidate();
frame.repaint();
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
TestLogin testLogin = new TestLogin();
testLogin.initUI();
testLogin.showLoginDialog();
}
});
}
}
There are several ways to do that.
E.g. you could reuse your 1st JFrame. Therefore remove the components you got on your 1st frame, add the ones for the 2nd and then repaint() the frame.
But I wouldn't consider that as good practice.
As Andrew Thompson suggested, you could also use a CardLayout to just initialize one JFrame, show your login-card and then switch to the fully initialized 2nd full-application card. This way you will get rid of those repaints.
You could also show your 2nd frame (your application first) and then use a modal JDialog to the let user log in.

Categories