setLocation of Label - java

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);
}
}

Related

Spaces between elements in GridLayout and GridBagLayout

I am trying to create a grid of text fields which I envision would look like this:
I am trying to use Swing in order to do this but am having trouble creating the grid. I have tried both GridBagLayout and GridLayout in order to accomplish this but have had the same issue with both - I am unable to remove spaces between the text fields.
The above image is using grid bag layout. I have tried to change the insets as well as the weights of each text field but have not been able to get rid of the spaces between the fields.
The grid layout is slightly better:
But it has the same problem. I tried adding each text field to a JPanel and then created an empty border for each panel but this also did not work.
I have attached the code for both implementations. I am not committed to using a JTextField so if there is some other element that a user can type into I would be willing to try that out as well. Any help getting rid of the spaces between each text field would be greatly appreciated!
GridBagLayoutDemo
class GridBagLayoutDemo {
public static void addComponentsToPane(Container pane) {
GridBagLayout gbl = new GridBagLayout();
pane.setLayout(gbl);
GridBagConstraints c = new GridBagConstraints();
int rows = 2;
int cols = 2;
for(int i = 0; i < (rows + 1) * 3; i++){
JTextField textField = new JTextField(1);
textField.setFont( new Font("Serif", Font.PLAIN, 30) );
JPanel tempPanel = new JPanel();
tempPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
tempPanel.add(textField);
c.gridx = i % (rows + 1);
c.gridy = i / (cols + 1);
c.gridheight = 1;
c.gridwidth = 1;
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
pane.add(tempPanel, c);
}
gbl.setConstraints(pane, c);
c.insets = new Insets(0,0,0,0);
}
public void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
GridBagLayoutDemo demo = new GridBagLayoutDemo();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
demo.createAndShowGUI();
}
});
}
}
GridLayoutDemo
class GridLayoutDemo {
public void createAndShowGUI() {
JFrame frame = new JFrame("GridLayout");
//frame.setOpacity(0L);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel parentPanel = new JPanel();
GridLayout layout = new GridLayout(3, 3, 0, 0);
layout.setHgap(0);
layout.setVgap(0);
parentPanel.setLayout(layout);
for(int i = 0 ; i < 9; i++){
JTextField textField = new JTextField();
textField.setHorizontalAlignment(JTextField.CENTER);
// JPanel tempPanel = new JPanel();
//textField.setBounds(0, 0, 10 , 10);
//textField.setFont( new Font("Serif", Font.PLAIN, 18));
//tempPanel.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
//tempPanel.add(textField);
// tempPanel.add(textField);
parentPanel.add(textField);
}
frame.add(parentPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
GridLayoutDemo demo = new GridLayoutDemo();
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
demo.createAndShowGUI();
}
});
}
}
I think you will find that this is a issue with the MacOS look and feel, as it adds a empty border around the text fields to allow for the focus highlight
You can see it highlighted below
The simplest way to remove it, is to remove or replace the border, for example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
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 TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
int rows = 3;
int cols = 3;
for (int index = 0; index < (rows * cols); index++) {
int row = index % rows;
int col = index / cols;
gbc.gridy = row;
gbc.gridx = col;
JTextField textField = new JTextField(4);
textField.setText(col + "x" + row);
textField.setBorder(new LineBorder(Color.DARK_GRAY));
add(textField, gbc);
}
}
}
}

Jpanels with Gridbaglayout inside a JPanel with GridbagLayout problems

I'm trying to get the CardLayout working correctly. - I have the first "card" in my deck", which i've called firstPanel (Gridbaglayout). Inside that panel i want some other panels with the same layout (Gridbaglayout) which ofc has some components.
as example under here - I'm showing one of the JPanels with Gridbaglayout that i want inside my firstPanel (Jpanel) called textFieldForPlayers.
I hope you understand what i mean. if not i'll try to explain it more detailed. :)
public void run() {
deck.setLayout(cl);
c = new GridBagConstraints();
firstPanel.setLayout(new GridBagLayout());
secondPanel.setLayout(new GridBagLayout());
thirdPanel.setLayout(new GridBagLayout());
GamePanel gamePanel = new GamePanel();
c.gridx = 0;
c.gridy = 0;
firstPanel.add(textFieldForPlayers(humanPLayers), c);
c.gridx = 0;
c.gridy = 1;
firstPanel.add(botPreferences(), c);
c.gridx = 0;
c.gridy = 2;
firstPanel.add(next = new JButton("Next"), c);
c.gridx = 0;
c.gridy = 0;
secondPanel.add(new JLabel("Bot preferences"), c);
c.gridx = 0;
c.gridy = 0;
thirdPanel.add(gamePanel, c);
deck.add(firstPanel, "1");
deck.add(secondPanel, "2");
deck.add(thirdPanel, "3");
cl.show(deck, "1");
events();
}
private JPanel textFieldForPlayers(int hplayers) {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
c = new GridBagConstraints();
JLabel text = new JLabel("Name of the human players");
c.gridx = 0;
c.gridy = 0;
panel.add(text, c);
boxes = new ArrayList<>();
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
boxes.add(new JTextField());
for (int i = 1; i <= hplayers; i++) {
boxes.get(i).setPreferredSize(new Dimension(165, 18));
c.gridx = 1;
c.gridy = i;
panel.add(boxes.get(i), c);
c.gridx = 0;
c.gridy = i;
panel.add(new JLabel("Player " + i + ": "), c);
}
return panel;
}
Picture 3 - This is what it looks like now
Picture 4 - Should be - 1 in the top, 2 in the middle and 3 in the bottom. All of them centeret.
Your CardLayout, cl, is not behaving as a true CardLayout, suggesting something is wrong with code not shown. Myself, I try to modularize my gui creation, including using a separate utility method to help create gridbagconstraints if any complex constraints are needed.
For example:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
#SuppressWarnings("serial")
public class GridBagEg extends JPanel {
public static final int PLAYER_COUNT = 5;
private CardLayout cardLayout = new CardLayout();
private JPanel deckPanel = new JPanel(cardLayout);
private NextAction nextAction = new NextAction("Next");
private PlayerPanel playerPanel = new PlayerPanel(PLAYER_COUNT);
private BotDifficultyPanel botDifficultyPanel = new BotDifficultyPanel();
public GridBagEg() {
deckPanel.add(playerPanel, PlayerPanel.NAME);
deckPanel.add(botDifficultyPanel, BotDifficultyPanel.NAME);
JPanel nextBtnPanel = new JPanel();
nextBtnPanel.add(new JButton(nextAction));
setLayout(new BorderLayout());
add(deckPanel, BorderLayout.CENTER);
add(nextBtnPanel, BorderLayout.PAGE_END);
}
private class NextAction extends AbstractAction {
public NextAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.next(deckPanel);
}
}
private static void createAndShowGui() {
GridBagEg mainPanel = new GridBagEg();
JFrame frame = new JFrame("GridBagEg");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
#SuppressWarnings("serial")
class BotDifficultyPanel extends JPanel {
public static final String NAME = "bot difficulty panel";
public static final String[] LEVELS = {"Easy", "Mid-level", "Difficult", "Holy Mother of God Difficulty"};
private JComboBox<String> difficultyCombo = new JComboBox<>(LEVELS);
public BotDifficultyPanel() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(new JLabel("Bot Difficulty:"), gbc);
gbc.gridx = 1;
gbc.insets = new Insets(0, 10, 0, 0);
add(difficultyCombo, gbc);
}
public String getSelectedDifficulty() {
String selection = (String) difficultyCombo.getSelectedItem();
return selection;
}
}
#SuppressWarnings("serial")
class PlayerPanel extends JPanel {
public static final String NAME = "player panel";
private static final String TITLE = "Name of Human Players";
private static final int EB_GAP = 10;
private static final int FIELD_COLUMNS = 15;
private static final int INS_GAP = 5;
private int playerMaxCount = 0;
private List<JTextField> playerFields = new ArrayList<>();
public PlayerPanel(int playerMaxCount) {
this.playerMaxCount = playerMaxCount;
Border outsideBorder = BorderFactory.createTitledBorder(TITLE);
Border insideBorder = BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP);
setBorder(BorderFactory.createCompoundBorder(outsideBorder, insideBorder));
setLayout(new GridBagLayout());
for (int i = 0; i < playerMaxCount; i++) {
JTextField playerField = new JTextField(FIELD_COLUMNS);
playerFields.add(playerField);
add(new JLabel("Player " + i + ":"), createGbc(0, i));
add(playerField, createGbc(1, i));
}
}
public String getFieldName(int index) {
if (index < 0 || index >= playerFields.size()) {
String text = "for playerFields index of " + index;
throw new IllegalArgumentException(text);
} else {
return playerFields.get(index).getText();
}
}
public int getPlayerMaxCount() {
return playerMaxCount;
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
// if x is 0, anchor to the left otherwise to the right
gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(INS_GAP, INS_GAP, INS_GAP, INS_GAP);
if (x == 0) {
gbc.insets.right = 4 * INS_GAP; // increase gap in between
}
return gbc;
}
}
Like:
CardLayout cl = new CardLayout();
JPanel contentPane = new JPanel();
JPanel firstPanel = new JPanel();
JPanel secondPanel = new JPanel();
contentPane.setlayout(cl);
firstPanel.add(new JButton("1"));
secondPanel.add(new JButton("2"));
contentPane.add(firstPanel, "1");
contentPane.add(secondPanel, "2");
cl.show(contentPane, "1");
So now the contentPane contains 2 JPanels inside it. and now we would be seeing everything on firstPanel right? :)

Making GridBagLayout more compact

I am trying to accomplish the following with GridBagLayout:
The frame will receive a collection of "fields" (JLabel, JTextField pairs), I want to arrange them in a 'Grid-like' fashion where a row will contain 2 such pairs (JLabel1 JField1 JLabel2 JField2). When a row has these four components, the next components are added to another row.
EDIT: I would like the components to start at the top of the panel
My code produces the following layout. I would like the components to be laid out more compactly (especially the vertical distance)
Here is the code:
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Test extends JFrame{
private JPanel _panel;
public Test() {
this.setDefaultCloseOperation(HIDE_ON_CLOSE);
this.setResizable(true);
this.setVisible(true);
Dimension size = new Dimension(600,600);
this.setMinimumSize(size);
this.setSize(size);
this.setPreferredSize(size);
_panel = new JPanel();
this.add(_panel);
}
public static void main(String[] args) {
Test t = new Test();
String[] labels = {"label1", "label2","label3","label4","label5"};
String[] fieldValues = {"value1","value2","value3","value4","value5"};
t.createFields(labels,fieldValues);
}
private void createFields(String[] labels, String[] fieldValues) {
_panel.setLayout(new GridBagLayout());
int col = 0;
int row = -1;
for(int i=0; i < labels.length;i++) {
JLabel label = new JLabel(labels[i] + ":", JLabel.TRAILING);
JTextField field = new JTextField(fieldValues[i]);
Dimension size = new Dimension(200,30);
field.setPreferredSize(size);
label.setLabelFor(field);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1;
c.weightx = 1;
c.ipadx = 0;
c.ipady = 0;
c.insets = new Insets(0,0,0,0);
c.anchor = GridBagConstraints.LINE_START;
c.gridx = col%4;
if(i%2 == 0) row++;
c.gridy = row;
_panel.add(label,c);
col++;
c.gridx = col%4;
_panel.add(field,c);
col++;
}
this.setVisible(true);
}
If you don't mind your elements being in center of panel (vertically and horizontally), then remove
c.weighty = 1;
c.weightx = 1;
from your code.
If center is wrong place, add
GridBagConstraints c = new GridBagConstraints();
c.gridx=4;
c.gridy=labels.length;
c.weightx=1;
c.weighty=1;
_panel.add(new JLabel(),c);
after your loop
If you want your GUI to be that size, but have the components in a compact size, then place them in their own JPanel, one that uses GridBagLayout, and then add that JPanel to your main GUI JPanel. If you want the components to fill the width, then have the main JPanel use BorderLayout, and add your GBL using JPanel BorderLayout.NORTH or .SOUTH whatever your need is.
For example:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class GridBagExample extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
public GridBagExample() {
super(new BorderLayout());
add(new GridBagUsingPanel(), BorderLayout.NORTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("GridBagExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GridBagExample());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class GridBagUsingPanel extends JPanel {
public static final int COLUMNS = 2;
public static final int ROWS = 3;
private static final int TF_COLS = 10;
private static int inset = 5;
private static final Insets INSETS = new Insets(inset, inset, inset, inset);
private static final Insets EXTRA_INSETS = new Insets(inset, inset, inset, 8 * inset);
private static final int EB_GAP = 10;
public GridBagUsingPanel() {
super(new GridBagLayout());
setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
for (int r = 0; r < ROWS; r++) {
for (int c = 0; c < COLUMNS; c++) {
addComponent(r, c);
}
}
}
private void addComponent(int r, int c) {
int count = 1 + r * COLUMNS + c;
JLabel label = new JLabel("label " + count);
JTextField textField = new JTextField("value " + count, TF_COLS);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 2 * c;
gbc.gridy = r;
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.insets = INSETS;
gbc.weightx = 0.1;
gbc.weighty = 1.0;
add(label, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.EAST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
if (c != COLUMNS - 1) {
gbc.insets = EXTRA_INSETS;
}
add(textField, gbc);
}
}

Accessing values of individual JTextFields created in a loop

Here is how I created the labels and JTextFields:
JPanel panel3 = new JPanel(new SpringLayout());
String[] labels = {"Non-animated image name:","Left animation image name:","Top animation image name:",
"Right animation image name:","Bottom animation image name:"};
for(int i=0; i<labels.length; i++){
JLabel l = new JLabel(labels[i],JLabel.TRAILING);
JTextField n = new JTextField(10);
panel3.add(l);
l.setLabelFor(n);
panel3.add(n);
}
SpringUtilities.makeCompactGrid(panel3,
5, 2,
6, 6,
6, 6);
Say for example, how would I access/get the value of the text in the JTextField with the label, "Top animation image name:"?
I know that usually, one can perform JTextField.getText(), but to me it looks like that wouldn't work here.
Thanks in advance!
This is just a specific example of the question:
how can I access an object created in a loop.
The answer is the same: put them in a collection or array. Note that the collection option has greater flexibility. For instance if you create a bunch of JLabel/JTextField associations, you could use a HashMap<String, JTextField> to associate the JTextField with a String.
For example:
Map<String, JTextField> fieldMap = new HashMap<String, JTextField>();
String[] labels = {"Non-animated image name:","Left animation image name:","Top animation image name:",
"Right animation image name:","Bottom animation image name:"};
for(int i=0; i<labels.length; i++){
JLabel l = new JLabel(labels[i],JLabel.TRAILING);
JTextField n = new JTextField(10);
panel3.add(l);
l.setLabelFor(n);
panel3.add(n);
fieldMap.put(labels[i], n);
}
// and then later you can get the text field associated with the String:
String text = fieldMap.get(labels[2]).getText();
Or for a full example:
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[] { "One", "Two",
"Three", "Four" };
InputForm inputForm = new InputForm(labelTexts);
int result = JOptionPane.showConfirmDialog(null, inputForm, "Enter Stuff Here",
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();
}
});
}
}
Each time you create a JLabel and a JTextField, store references to each of them inside a new instance of a container class.
For example:
private class LabelTextFieldContainer {
JLabel label;
JTextField textField;
//Constructor goes here...
}
for(int i=0; i<labels.length; i++){
JLabel l = new JLabel(labels[i],JLabel.TRAILING);
JTextField n = new JTextField(10);
panel3.add(l);
l.setLabelFor(n);
panel3.add(n);
containerList.add( new Container(l, n) ); //Instantiate List<LabelTextFieldContainer> containerList somewhere else
}

Cant set textLabel because it contradicts parseDouble

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.

Categories

Resources