I need a text field on a label but when i run this code there is no text field on the screen. How can i fix it.
JFrame jf = new JFrame() ;
JPanel panel = new JPanel() ;
JLabel label = new JLabel() ;
JTextField tField = new JTextField("asd" , 10) ;
label.add( tField ) ;
panel.add( label ) ;
jf.setSize( 500,400 ) ;
jf.add( panel ) ;
jf.setVisible(true) ;
JLabel's have no default layout manager, and so while your JTextField is being added tot he JLabel, it's not showing because the label has no idea how to show it.
There can be several ways to solve this depending on what you're trying to achieve:
Give the JLabel a layout manager, and then add the JTextField to it: but then the JTextField covers the JLabel, its text (if it has any) and its icon (if it has one), not good.
Create a JPanel to hold both, and give it an appropriate layout manager: probably a good bet.
Add them both to the same JPanel, using a layout manager that can easily place them in association: another good bet. GridBagLayout works well for this.
Don't forget to also call the JLabel's setLabelFor(...) method to associate it tightly with the JTextField, as per the JLabel Tutorial
For example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class GridBagEg {
private static void createAndShowGui() {
PlayerEditorPanel playerEditorPane = new PlayerEditorPanel();
int result = JOptionPane.showConfirmDialog(null, playerEditorPane, "Edit Player",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
// TODO: do something with info
for (PlayerEditorPanel.FieldTitle fieldTitle : PlayerEditorPanel.FieldTitle.values()) {
System.out.printf("%10s: %s%n", fieldTitle.getTitle(),
playerEditorPane.getFieldText(fieldTitle));
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
enum FieldTitle {
NAME("Name", KeyEvent.VK_N), SPEED("Speed", KeyEvent.VK_P), STRENGTH("Strength", KeyEvent.VK_T);
private String title;
private int mnemonic;
private FieldTitle(String title, int mnemonic) {
this.title = title;
this.mnemonic = mnemonic;
}
public String getTitle() {
return title;
}
public int getMnemonic() {
return mnemonic;
}
};
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
public PlayerEditorPanel() {
setLayout(new GridBagLayout());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Editor"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
GridBagConstraints gbc;
for (int i = 0; i < FieldTitle.values().length; i++) {
FieldTitle fieldTitle = FieldTitle.values()[i];
JLabel label = new JLabel(fieldTitle.getTitle() + ":", JLabel.LEFT);
JTextField textField = new JTextField(10);
label.setDisplayedMnemonic(fieldTitle.getMnemonic());
label.setLabelFor(textField);
gbc = createGbc(0, i);
add(label, gbc);
gbc = createGbc(1, i);
add(textField, gbc);
fieldMap.put(fieldTitle, textField);
}
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH : GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
public String getFieldText(FieldTitle fieldTitle) {
return fieldMap.get(fieldTitle).getText();
}
}
Which displays as
Note that the JLabels have underlines on mnemonic chars, chars that when pressed in alt-key combination will bring the focus to the JTextField that the JLabel was linked to via, setLabelFor(...), and is caused by this code:
FieldTitle fieldTitle = FieldTitle.values()[i]; // an enum that holds label texts
JLabel label = new JLabel(fieldTitle.getTitle() + ":", JLabel.LEFT); // create JLabel
JTextField textField = new JTextField(10); // create JTextField
// set the label's mnemonic -- brings focus to the linked text field
label.setDisplayedMnemonic(fieldTitle.getMnemonic());
// *** here we *link* the JLabel with the JTextField
label.setLabelFor(textField);
Related
I am making authentication GUI which should contain 2 text fields, username JTextField and password JPasswordField. I want to make the password field be below the username field. my current code is as follows:
public class GuiAuthentication extends JFrame {
private static final int WIDTH = 1000;
private static final int HEIGHT = 650;
private JTextField tfUsername;
private JPasswordField tfPassword;
public GuiAuthentication() {
try {
setTitle("Metaspace Launcher");
getContentPane().setLayout(new FlowLayout());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
tfUsername = new JTextField("Username");
tfPassword = new JPasswordField("********");
tfUsername.setBounds(10, 10, 50, 20);
tfPassword.setBounds(10, 50, 50, 20);
getContentPane().add(tfUsername);
getContentPane().add(tfPassword);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setMinimumSize (new Dimension(WIDTH, HEIGHT));
setMaximumSize (new Dimension(WIDTH, HEIGHT));
setResizable(false);
requestFocus();
setLocationRelativeTo(null);
setVisible(true);
} catch (final Exception ex) {
ex.printStackTrace();
System.exit(ex.toString().hashCode());
}
}
#Override
public void paint(final Graphics g) {
super.paint(g);
Gui.drawBackground(this, g, WIDTH, HEIGHT);
Gui.drawRect(g, WIDTH/3, HEIGHT/3 + 20, 325, 200, 0xAA000000);
}
However, this results in the password field being located against the username field, and both of them are centered, and not located at X position 10 which I specify:
--> Screenshot (click)
Is the problem in the layout I currently use (FlowLayout)? If so, which one should I use then? If not, what else might be wrong?
Tried using GridBagLayout as well. It results in this (fields side by side, centered):
Your GridBagLayout attempt images suggest that either you're not using GridBagConstraints when adding components or that you're using the incorrectly.
If you want to center your text components in the GUI, one over the other, and say put them in their own box, then use a GridBagLayout for the container that holds them, and also pass in appropriate GridBagConstraints that will work well with your desire. This will mean giving the constraints an appropriate gridx and gridy value to match where in the grid you wish to place the component. Also you will want to anchor the component correctly, and you will usually want to set the constraints insets to give an empty space buffer around your components so that they don't crowd each other. Myself, when I do something like this, I often use a 4 x 4 grid with two rows and two columns including a column of JLabels on the left so the user knows what each text component in the right column represents. I often use a helper method to help create my constraints, something like this:
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.fill = GridBagConstraints.HORIZONTAL; // stretch components horizontally
gbc.weightx = 1.0;
gbc.weighty = 0.0; // increase if you want component location to stretch vert.
// I_GAP is a constant and is the size of the gap around
// each component
gbc.insets = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
// if the x value is odd, anchor to the left, otherwise if even to the right
gbc.anchor = x % 2 == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
return gbc;
}
And then I'd use it like this:
JPanel innerPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("User Name:");
userNameLabel.setForeground(Color.LIGHT_GRAY);
innerPanel.add(userNameLabel, createGbc(0, 0)); // add w/ GBC
innerPanel.add(tfUsername, createGbc(1, 0)); // etc...
JLabel passwordLabel = new JLabel("Password:");
passwordLabel.setForeground(Color.LIGHT_GRAY);
innerPanel.add(passwordLabel, createGbc(0, 1));
innerPanel.add(tfPassword, createGbc(1, 1));
A working example could look like so:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.Border;
#SuppressWarnings("serial")
public class MetaSpaceLauncherPanel extends JPanel {
// path to a public starry image
public static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/"
+ "commons/thumb/b/be/Milky_Way_at_Concordia_Camp%2C_Karakoram_Range%2"
+ "C_Pakistan.jpg/1280px-Milky_Way_at_Concordia_Camp%2C_Karakoram_Range"
+ "%2C_Pakistan.jpg";
private static final int I_GAP = 10;
private static final int COLS = 15;
private JTextField tfUsername = new JTextField(COLS);
private JPasswordField tfPassword = new JPasswordField(COLS);
private BufferedImage background = null;
public MetaSpaceLauncherPanel(BufferedImage background) {
this.background = background;
// close window if enter pressed and data within fields
ActionListener listener = e -> {
String userName = tfUsername.getText().trim();
char[] password = tfPassword.getPassword();
Window window = SwingUtilities.getWindowAncestor(MetaSpaceLauncherPanel.this);
if (userName.isEmpty() || password.length == 0) {
// both fields need to be filled!
String message = "Both user name and password fields must contain data";
String title = "Invalid Data Entry";
JOptionPane.showMessageDialog(window, message, title, JOptionPane.ERROR_MESSAGE);
} else {
// simply close the dialog
window.dispose();
}
};
tfUsername.addActionListener(listener);
tfPassword.addActionListener(listener);
JPanel innerPanel = new JPanel(new GridBagLayout());
innerPanel.setOpaque(false);
Border outerBorder = BorderFactory.createEtchedBorder();
Border innerBorder = BorderFactory.createEmptyBorder(I_GAP, I_GAP, I_GAP, I_GAP);
Border border = BorderFactory.createCompoundBorder(outerBorder, innerBorder);
innerPanel.setBorder(border);
JLabel userNameLabel = new JLabel("User Name:");
userNameLabel.setForeground(Color.LIGHT_GRAY);
innerPanel.add(userNameLabel, createGbc(0, 0));
innerPanel.add(tfUsername, createGbc(1, 0));
JLabel passwordLabel = new JLabel("Password:");
passwordLabel.setForeground(Color.LIGHT_GRAY);
innerPanel.add(passwordLabel, createGbc(0, 1));
innerPanel.add(tfPassword, createGbc(1, 1));
setLayout(new GridBagLayout());
add(innerPanel); // add without constraints to center it
}
public String getUserName() {
return tfUsername.getText();
}
public char[] getPassword() {
return tfPassword.getPassword();
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.fill = GridBagConstraints.HORIZONTAL; // stretch components horizontally
gbc.weightx = 1.0;
gbc.weighty = 0.0; // increase if you want component location to stretch vert.
// I_GAP is a constant and is the size of the gap around
// each component
gbc.insets = new Insets(I_GAP, I_GAP, I_GAP, I_GAP);
// if the x value is odd, anchor to the left, otherwise if even to the right
gbc.anchor = x % 2 == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
return gbc;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
g.drawImage(background, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || background == null) {
return super.getPreferredSize();
}
int w = background.getWidth();
int h = background.getHeight();
return new Dimension(w, h);
}
private static void createAndShowGui() {
BufferedImage img = null;
try {
// just using this as an example image, one available to all
// you would probably use your own image
URL imgUrl = new URL(IMG_PATH); // online path to starry image
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1); // no image available -- exit!
}
MetaSpaceLauncherPanel launcherPanel = new MetaSpaceLauncherPanel(img);
JDialog dialog = new JDialog(null, "MetaSpace Launcher", ModalityType.APPLICATION_MODAL);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.getContentPane().add(launcherPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
// test to see if we can get the data
String userName = launcherPanel.getUserName();
char[] password = launcherPanel.getPassword();
// don't convert password into String as I'm doing below as it is now
// not secure
String message = String.format("<html>User Name: %s<br/>Password: %s</html>", userName,
new String(password));
JOptionPane.showMessageDialog(null, message);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I'm wanting to put several JTextFields into a JOptionPane so that I can validate the information put within them. I know that showInputDialog() will produce one Input, but how would I go about implementing 3/4
EDIT: (At run-time it just shows one input field)
//JDIALOG(FOR END PAYMENT)
dialogPanel = new JPanel();
creditCardNoInput = new JTextField();
sortCodeInput = new JTextField();
secNoInput = new JTextField();
cardHolderName = new JTextField();
dialogPanel.add(creditCardNoInput);
dialogPanel.add(sortCodeInput);
dialogPanel.add(secNoInput);
dialogPanel.add(cardHolderName);
int result = JOptionPane.showConfirmDialog(null, dialogPanel,
"Please Enter your card details", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
//Execute desired code
Use a JPanel.
Put your JTextFields, along with your JLabels (since you'll likely need these as well), into a JPanel or JPanels, and put the main JPanel into the JOptionPane. You can put a complete complex GUI into JPanels and display this in a JOptionPane if desired.
For example:
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class ComplexOptionPane extends JPanel {
private PlayerEditorPanel playerEditorPanel = new PlayerEditorPanel();
private JTextArea textArea = new JTextArea(12, 30);
public ComplexOptionPane() {
textArea.setEditable(false);
textArea.setFocusable(false);
textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 16));
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton(new AbstractAction("Get Player Information") {
#Override
public void actionPerformed(ActionEvent arg0) {
int result = JOptionPane.showConfirmDialog(null, playerEditorPanel,
"Edit Player JOptionPane", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
for (PlayerEditorPanel.FieldTitle fieldTitle : PlayerEditorPanel.FieldTitle
.values()) {
textArea.append(String.format("%10s: %s%n",
fieldTitle.getTitle(),
playerEditorPanel.getFieldText(fieldTitle)));
}
}
}
}));
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setLayout(new BorderLayout(5, 5));
add(new JScrollPane(textArea), BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
ComplexOptionPane mainPanel = new ComplexOptionPane();
JFrame frame = new JFrame("ComplexOptionPane");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class PlayerEditorPanel extends JPanel {
enum FieldTitle {
NAME("Name"), SPEED("Speed"), STRENGTH("Strength"), HEALTH("Health");
private String title;
private FieldTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
};
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private Map<FieldTitle, JTextField> fieldMap = new HashMap<FieldTitle, JTextField>();
public PlayerEditorPanel() {
setLayout(new GridBagLayout());
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Player Editor"),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
GridBagConstraints gbc;
for (int i = 0; i < FieldTitle.values().length; i++) {
FieldTitle fieldTitle = FieldTitle.values()[i];
gbc = createGbc(0, i);
add(new JLabel(fieldTitle.getTitle() + ":", JLabel.LEFT), gbc);
gbc = createGbc(1, i);
JTextField textField = new JTextField(10);
add(textField, gbc);
fieldMap.put(fieldTitle, textField);
}
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
public String getFieldText(FieldTitle fieldTitle) {
return fieldMap.get(fieldTitle).getText();
}
}
Also -- this answer
An MCVE using your code example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.border.Border;
public class Foo1 {
private static final Insets WEST_INSETS = new Insets(5, 0, 5, 5);
private static final Insets EAST_INSETS = new Insets(5, 5, 5, 0);
private JPanel dialogPanel;
private JTextField creditCardNoInput;
private JTextField sortCodeInput;
private JTextField secNoInput;
private JTextField cardHolderName;
public Foo1() {
dialogPanel = new JPanel(new GridBagLayout());
Border titleBorder = BorderFactory.createTitledBorder("Credit Card Information");
Border emptyBorder = BorderFactory.createEmptyBorder(10, 10, 10, 10);
Border combinedBorder = BorderFactory.createCompoundBorder(titleBorder, emptyBorder);
dialogPanel.setBorder(combinedBorder);
creditCardNoInput = new JTextField(5);
sortCodeInput = new JTextField(5);
secNoInput = new JTextField(5);
cardHolderName = new JTextField(5);
dialogPanel.add(new JLabel("Credit Card Number:"), createGbc(0, 0));
dialogPanel.add(creditCardNoInput, createGbc(1, 0));
dialogPanel.add(new JLabel("Sort Code:"), createGbc(0, 1));
dialogPanel.add(sortCodeInput, createGbc(1, 1));
dialogPanel.add(new JLabel("Second Number:"), createGbc(0, 2));
dialogPanel.add(secNoInput, createGbc(1, 2));
dialogPanel.add(new JLabel("Cardholder Name:"), createGbc(0, 3));
dialogPanel.add(cardHolderName, createGbc(1, 3));
int result = JOptionPane.showConfirmDialog(null, dialogPanel,
"Please Enter your card details", JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
// Execute desired code
}
}
private static GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.anchor = (x == 0) ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = (x == 0) ? GridBagConstraints.BOTH
: GridBagConstraints.HORIZONTAL;
gbc.insets = (x == 0) ? WEST_INSETS : EAST_INSETS;
gbc.weightx = (x == 0) ? 0.1 : 1.0;
gbc.weighty = 1.0;
return gbc;
}
private static void createAndShowGui() {
new Foo1();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Solution:
When I was running my code, for some reason it was preferring my other GUI to start up. I only found this out when I commented out the code and the JOptionPane was still executing, so I manually selected my GUI, ran it, and the 4 boxed appeared.
P.S Please vote this answer so that I can get a badge. Thanks! :)
I want to be able to click a JButton from my JFrame which opens up another window and in this 2nd window, I want to be able to input something into a text field on that window and get the information from that text field.
JButton myButton = new JButton("Click Here!");
public void actionPerformed (ActionEvent event)
{
if (event.getSource() == myButton) {
// open the new window }
I know how to define the components of this new JFrame, but how will I write an actionPerformed event for that new window since nesting modules isn't allowed?
Is there a way to customize the contents of the modal dialog window? For instance if I wanted 2 text fields in the pop up window (so it can take 2 inputs)? What if I wanted to change the "OK"/"Cancel" buttons to have different labels and/or behave differently?
A modal dialog (JDialog) or a JOptionPane, like a JFrame, can hold a JPanel that has the most complex GUI that you can imagine including nesting other JPanels that use whatever layouts are necessary and that contain multiple components. For example, the following code creates JOptionPane that displays a JPanel that holds a number of JTextFields, all extractable after the JOptionPane returns:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
public class ComplexDialogPanel extends JPanel {
public static final String[] LABEL_TEXTS = { "Last Name", "First Name",
"Address", "City", "State", "Zip" };
public static final int COLS = 8;
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public ComplexDialogPanel() {
setLayout(new GridBagLayout());
for (int i = 0; i < LABEL_TEXTS.length; i++) {
String labelTxt = LABEL_TEXTS[i];
add(new JLabel(labelTxt), createGbc(0, i));
JTextField textField = new JTextField(COLS);
labelFieldMap.put(labelTxt, textField);
add(textField, createGbc(1, i));
}
setBorder(BorderFactory.createTitledBorder("Enter User Information"));
}
public String getText(String labelText) {
JTextField textField = labelFieldMap.get(labelText);
if (textField != null) {
return textField.getText();
} else {
throw new IllegalArgumentException(labelText);
}
}
public static GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = gbc.weightx;
if (x == 0) {
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(3, 3, 3, 8);
} else {
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(3, 3, 3, 3);
}
return gbc;
}
private static void createAndShowGui() {
ComplexDialogPanel mainPanel = new ComplexDialogPanel();
int optionType = JOptionPane.DEFAULT_OPTION;
int messageType = JOptionPane.PLAIN_MESSAGE;
Icon icon = null;
String[] options = { "Submit", "Cancel" };
Object initialValue = options[0];
int reply = JOptionPane.showOptionDialog(null, mainPanel,
"Get User Information", optionType, messageType, icon, options,
initialValue);
if (reply == 0) {
System.out.println("Selections:");
for (String labelText : LABEL_TEXTS) {
System.out.printf("%12s: %s%n", labelText,
mainPanel.getText(labelText));
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have an ItemListener that looks like this:
private class Listener implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
calculate();
}
}
At the bottom of my calculate() method, I set these labels like this:
subtotalLbl.setText("\t\t\t\t\t\t\t\tSubtotal:\t\t\t\t\t\t\t\t\t " + String.valueOf(determinedSubTotal + priceIncrease) + "\t\t\t\t\t\t\t\t\t");
taxLbl.setText("\t\t\t\t\t\t\t\tTax:\t\t\t\t\t\t\t\t\t " + String.valueOf(determinedTax + priceIncrease) + "\t\t\t\t\t\t\t\t\t");
totalLbl.setText("\t\t\t\t\t\t\tTotal:\t\t\t\t\t\t\t\t\t " + String.valueOf(determinedTotal + priceIncrease) + "\t\t\t\t\t\t\t\t\t");
Then I have an ActionListener that uses the text from the totalLbl for parseDouble
private class BtnClicked implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String input = totalLbl.getText().trim();
Double parsedString = Double.parseDouble(input) * 0.20;
Object src = e.getSource();
if(src == submit)
{
JOptionPane.showMessageDialog(null,"Thank you for your order - the tip will be " + fmt.format(parsedString), "Thank you" , JOptionPane.INFORMATION_MESSAGE);
}
else if(src == cancel)
{
JOptionPane.showMessageDialog(null,"Order was canceled" ,"Order Canceled" , JOptionPane.INFORMATION_MESSAGE);
}
}
Obviously the program is crashing at the line inside of the BtnClicked's actionPerformed method where parseDouble(input) is at, because the totalLbl JLabel has "Total:" in it.. where else would I set this or how would I work around this? The "Total:" is required. (can't use split() )
Here's a screenshot of what the entire JFrame looks like, program crashes when clicking the submit button:
Create two JLables, one which says Total: the other which actually holds the total value.
So your total calculation would look more like...
totalLblText.setText("Total:");
totalLbl.setText(String.valueOf(determinedTotal + priceIncrease));
Then you won't need to care.
You should make better use of your layout managers in order to support the formatting your trying to achieve rather than using formatting characters like \t, these will always end up in a mess
Updated with layout example
This simple example demonstrates how you might use a layout managers (and a technique known as compound layouts) and relieve the need to try and use a single label for displaying more information then it should...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestLayout {
public static void main(String[] args) {
new TestLayout();
}
public TestLayout() {
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 {
private JTextField numberOfPizzas;
private JCheckBox pepperoni;
private JCheckBox sausage;
private JCheckBox peppers;
private JCheckBox onions;
private JCheckBox mushrooms;
private JCheckBox extracheese;
private JLabel lblSubTotal;
private JLabel lblTax;
private JLabel lblTotal;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
JPanel header = new JPanel();
JPanel extras = new JPanel(new GridBagLayout());
JPanel totals = new JPanel(new GridBagLayout());
add(header, gbc);
gbc.gridy++;
add(extras, gbc);
gbc.gridy++;
add(totals, gbc);
numberOfPizzas = new JTextField(5);
header.add(new JLabel("Number of pizzas"));
header.add(numberOfPizzas);
gbc = new GridBagConstraints();
pepperoni = new JCheckBox("Pepperoni");
sausage = new JCheckBox("Sausage");
peppers = new JCheckBox("Peppers");
onions = new JCheckBox("Onions");
mushrooms = new JCheckBox("mushrooms");
extracheese = new JCheckBox("Extra Cheeses");
JCheckBox left[] = new JCheckBox[] {pepperoni, peppers, mushrooms};
JCheckBox right[] = new JCheckBox[] {sausage, onions, extracheese};
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx = 0;
gbc.gridy = 0;
add(left, extras, 0, 1, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
add(right, extras, 0, 1, gbc);
gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
gbc.insets = new Insets(2, 12, 2, 12);
totals.add(new JLabel("Subtotal:"), gbc);
gbc.gridy++;
totals.add(new JLabel("Tax:"), gbc);
gbc.gridy++;
totals.add(new JLabel("Total:"), gbc);
gbc.weightx = 0;
gbc.gridx = 1;
gbc.gridy = 0;
lblSubTotal = new JLabel("8.0");
lblTax = new JLabel("0.78");
lblTotal = new JLabel("8.78");
totals.add(lblSubTotal, gbc);
gbc.gridy++;
totals.add(lblTax, gbc);
gbc.gridy++;
totals.add(lblTotal, gbc);
}
protected void add(JComponent[] comps, JComponent parent, int deltaX, int deltaY, GridBagConstraints gbc) {
for (JComponent comp : comps) {
parent.add(comp, gbc);
gbc.gridy += deltaY;
gbc.gridx += deltaX;
}
}
}
}
Lots of different ways to do this, the easiest is probably:
String[] parts = totalLbl.getText().split(":");
String input = parts[1].trim();
Double parsedString = Double.parseDouble(input) * 0.20;
you can do this
str = str.replaceAll("\\D+","");
this will delete non digits from the string
so you would want it to be like this
Double parsedString = Double.parseDouble(input.replaceAll("\\D+","")*0.20);
You can use separate widgets for the label and the value. E.g. The total label, create a JLabel object and set the text with static value "Total:", then for the total value, create a JTextField object and set the text with the actual value. When submitting, get the value from the textfield instead of from the label. Don't forget to call setEditable(false) to the textfield because the textfield is meant to display the value only, not to accept input.
I have all of the labels working correctly but the userLabel[3] is not positioning properly
No matter what I do, the label "Color:" always shows up on the frame with a x-coordinate of 0 and a y-coordinate that is half way down the frame.
JLabel[] userLabel = new JLabel[4];
for(int p = 0; p < userLabel.length; p++){
userLabel[p] = new JLabel();
userLabel[p].setSize(100,50);
frameSetUp.add(userLabel[p]);
}
userLabel[0].setText("Width of Frame:");
userLabel[1].setText("Height of Frame:");
userLabel[2].setText("# OF Balls:");
userLabel[3].setText("Color:");
userLabel[0].setLocation(10,35);
userLabel[1].setLocation(10,85);
userLabel[2].setLocation(10,135);
userLabel[3].setLocation(0,0); //no matter what coordinates I change this too, it wont reposition
Image:
[IMG]http://i41.tinypic.com/23jfo9l.png[/IMG]
http://i41.tinypic.com/23jfo9l.png
Don't use setLocation, setBounds, null layouts or absolute positioning.
Instead use the layout managers including perhaps nested JPanels, each using its own layout manager to achieve pleasing easy to maintain GUI's.
For more help, show a picture of what you're trying to achieve, what you actually are achieving, and post a minimal working example, code that is small, that compiles and runs, and shows us your problem.
e.g.,
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class InputForm extends JPanel {
private static final int COLUMNS = 10;
private static final int GAP = 3;
private static final Insets LABEL_INSETS = new Insets(GAP, GAP, GAP, 15);
private static final Insets TEXTFIELD_INSETS = new Insets(GAP, GAP, GAP, GAP);
private String[] labelTexts;
private Map<String, JTextField> fieldMap = new HashMap<String, JTextField>();
public InputForm(String[] labelTexts) {
this.labelTexts = labelTexts;
setLayout(new GridBagLayout());
for (int i = 0; i < labelTexts.length; i++) {
String text = labelTexts[i];
JTextField field = new JTextField(COLUMNS);
fieldMap.put(text, field);
addLabel(text, i);
addTextField(field, i);
}
}
public String[] getLabelTexts() {
return labelTexts;
}
private void addTextField(JTextField field, int row) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.gridx = 1;
gbc.gridy = row;
gbc.anchor = GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = TEXTFIELD_INSETS;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
add(field, gbc);
}
private void addLabel(String text, int row) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.gridx = 0;
gbc.gridy = row;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = LABEL_INSETS;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
add(new JLabel(text), gbc);
}
public String getFieldText(String key) {
String text = "";
JTextField field = fieldMap.get(key);
if (field != null) {
text = field.getText();
}
return text;
}
private static void createAndShowGui() {
String[] labelTexts = new String[] { "Width of Frame:",
"Height of Frame:", "# OF Balls:", "Color:" };
InputForm inputForm = new InputForm(labelTexts);
int result = JOptionPane.showConfirmDialog(null, inputForm, "Input Form",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
for (String text : labelTexts) {
System.out.printf("%20s %s%n", text, inputForm.getFieldText(text));
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Which will display like so:
The beauty of this code, is if you wish to add another field, say a line thickness field, and want to add it so that it is second to last, then the only change needed to the code would be to change this:
String[] labelTexts = new String[] { "Width of Frame:",
"Height of Frame:", "# OF Balls:", "Color:" };
to this:
String[] labelTexts = new String[] { "Width of Frame:",
"Height of Frame:", "# OF Balls:", "Line Thickness:", "Color:" };
Which results in:
No need to have to calculate how to change the Color label or JTextField's locations as the layout manager does all the hard work for you.
Finally got the answer try increasing the size of the JLabel array by 1 and run it will work fine
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Labelss{
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setBounds(50, 50, 700, 550);
JLabel[] userLabel = new JLabel[6];
for(int p = 0; p < userLabel.length; p++){
userLabel[p] = new JLabel();
}
userLabel[0].setBounds(10,35,100,50);
userLabel[1].setBounds(10,85,100,50);
userLabel[2].setBounds(10,135,100,50);
userLabel[3].setBounds(10,185,100,50);
userLabel[4].setBounds(10,235,100,50);
userLabel[0].setText("Width of Frame:");
userLabel[1].setText("Height of Frame:");
userLabel[2].setText("# OF Balls:");
userLabel[3].setText("Color:");
userLabel[4].setText("Stack overflow:");
for(int p = 0; p < userLabel.length; p++){
frame.add(userLabel[p]);
}
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}