creating JFrame with variable amount of JLabels - java

I am currently trying to make a JFrame which should contain one String followed by a text entry field for each entry in a HashMap (longToShortNamesMap). Currently I am displaying the entries as follws in a JOptionPane:
String paneMessage = "";
List keys = new ArrayList(longToShortNameMap.keySet());
for(int i = 0 ; i < keys.size();i++){
paneMessage += "Field name " + keys.get(i) + " has been shortened to " + longToShortNameMap.get(keys.get(i)) + "\n";
}
JOptionPane.showMessageDialog (null, paneMessage, "Data Changed", JOptionPane.INFORMATION_MESSAGE);
Instead, I would like a frame to appear which will have the same message appear but will have the "longToShortNameMap.get(keys.get(i))" part appear in an editable text field. I'm not quite sure how ot go about this but this is what I have so far which is popping one JFrame with one label (which is not an editable text field).
private static void showFrames(Map<String,String> longToShortNameMap) {
JFrame frame = new JFrame("Data Changed");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 500);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel(new BorderLayout());
List<String> keys = new ArrayList(longToShortNameMap.keySet());
for (String key : keys) {
JLabel label = new JLabel(longToShortNameMap.get(key));
panel.add(label);
}
frame.add(panel);
}
EDIT: As a contextual side note, I am doing this because field names are limited to 10 characters in a place in my application so I am forced to trim the field names down to 10 characters. When I do this, I want to notify the user what each trimmed field has been trimmed to and additionally give them the option to change the trimmed named

Your main issue is your choice of layout manager. BorderLayout allows one component in each of its 5 areas. When you're adding your labels to the center area (the default), you keep replacing the last one instead of appending it. I recommend adding each label and JTextField (your editable field) to a GridLayout panel.
private static void showFrames(Map<String,String> longToShortNameMap) {
JFrame frame = new JFrame("Data Changed");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(400, 500);
frame.setResizable(true);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel(new GridLayout(0, 2)); //use gridlayout
List<String> keys = new ArrayList(longToShortNameMap.keySet());
for (String key : keys) {
JLabel label = new JLabel(key); // your label is the key itself
JTextField textField = new JTextField(longToShortNameMap.get(key));
panel.add(label); // Populate textfield with the key's value
panel.add(textField);
}
frame.add(panel);
}

Related

Medium Sized Quiz Application, Troubles Dynamically generating Labels & RadioButtons

So this snippet of code is from an application I'm building for my job. One window gets the user's name, then they select a category, then they take the quiz.
static void QuestionsWindow(){
ProtemInservices.SetActiveQuestions();
JFrame frame = new JFrame("Quiz for: " + ProtemInservices.testeeName);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<JLabel> questions = new Vector<JLabel>();
Vector<ButtonGroup> questionsGroup = new Vector<ButtonGroup>();
Vector<JRadioButton> choices = new Vector<JRadioButton>();
Vector<String> choicesString = new Vector<String>();
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
int counter = 0;
for(int i=0;i<ProtemInservices.ActiveQuestions.size();i++){
choicesString = new Vector<String>();
questions.add(new JLabel(ProtemInservices.ActiveQuestions.elementAt(i).GetQuestionText()));
ProtemInservices.ActiveQuestions.elementAt(i).CopyChoices(choicesString);
questionsGroup.add(new ButtonGroup());
frame.add(questions.elementAt(i));
for(int j=0;j<choicesString.size();j++,counter++){
choices.add(new JRadioButton(choicesString.elementAt(j)));
questionsGroup.elementAt(i).add(choices.elementAt(j));
frame.add(choices.elementAt(counter));
}
}
frame.setMinimumSize(new Dimension(1280, 1024));
//Display the window.
//frame.pack();
frame.setVisible(true);
}
My problem is dynamically creating RadioButtons and Labels. The labels come out as expect, but the nested loop is supposed to create a set of RadioButtons for each Label. I have only tested this with two different categories, the first creates the labels then creates the RadioButtons, but only for the first label and after it has created all other labels. The second category creates the labels as it should but the RadioButtons are real wonky, two come after the second label and another two are at the end.
First Category GUI
Any hints would be extremely appreciated.
static void QuestionsWindow(){
ProtemInservices.SetActiveQuestions();
JFrame frame = new JFrame("Quiz for: " + ProtemInservices.testeeName);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vector<JLabel> questions = new Vector<JLabel>();
Vector<ButtonGroup> questionsGroup = new Vector<ButtonGroup>();
Vector<JRadioButton> choices = new Vector<JRadioButton>();
Vector<String> choicesString = new Vector<String>();
frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
int counter = 0;
for(int i=0;i<ProtemInservices.ActiveQuestions.size();i++){
choicesString = new Vector<String>();
questions.add(new JLabel(ProtemInservices.ActiveQuestions.elementAt(i).GetQuestionText()));
ProtemInservices.ActiveQuestions.elementAt(i).CopyChoices(choicesString);
questionsGroup.add(new ButtonGroup());
frame.add(questions.elementAt(i));
for(int j=0;j<choicesString.size();j++,counter++){
choices.add(new JRadioButton(choicesString.elementAt(j)));
questionsGroup.elementAt(i).add(choices.elementAt(counter));
frame.add(choices.elementAt(counter));
}
}
frame.setMinimumSize(new Dimension(1280, 1024));
//Display the window.
//frame.pack();
frame.setVisible(true);
}
The logic is laid out above in the comments on how we came to this solution.

TabbedPane iterate for loop

I received in loop iteration as:
Tab 1
Tab 2
On beginning code I have panel, tabbedpane and scrollpane:
JPanel panel = new JPanel();
JTabbedPane tabbedPane = new JTabbedPane();
JScrollPane scrollPanel = new JScrollPane();
Then receive through iteration using Event JList and receive Tab 1 and Tab 2, but can't add two tabs. So here is iterate and receive Tab 1 and Tab 2 into tab_name variable:
String tab_name = ap_data_array[2]; // Tab 1, Tab 2
tabbedPane.addTab(tab_name, panel); // Here add only once tab Tab 1
this.jPanel1.add(tabbedPane, BorderLayout.CENTER);
scrollPanel.setViewportView(new JLabel(ap_data_array[2]));
tabbedPane.setBounds(0, 0, 530, 500);
this.jPanel1.setSize(530,500);
System.out.println(tab_name); // Tab 1 then Tab 2
A result will only render 1 tab, Tab 1.
Here is full code:
String lines[] = loaded_data.split("\\r?\\n");
for (String item : lines)
{
String pattern = "AP.*";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(item);
// Added
JPanel panel = new JPanel();
JTabbedPane tabbedPane = new JTabbedPane();
JScrollPane scrollPanel = new JScrollPane();
if (m.find())
{
String ap_data = m.group(0);
String[] ap_data_array = ap_data.split("\\|", -1);
if (ap_data_array[0].equals("AP"))
{
JList source = (JList)evt.getSource();
String selected = source.getSelectedValue().toString();
// type selected
if (ap_data_array[1].equals(selected))
{
// tabs name
//ap_data_array[2] // "Tab 1" "Tab 2"
String tab_name = ap_data_array[2];
tabbedPane.addTab(tab_name, panel);
this.jPanel1.add(tabbedPane, BorderLayout.CENTER);
scrollPanel.setViewportView(new JLabel(ap_data_array[2]));
tabbedPane.setBounds(0, 0, 530, 500);
this.jPanel1.setSize(530,500);
System.out.println(tab_name); // "Tab 1" "Tab 2"
}
}
}
}
SOLUTION:
private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {
if (evt.getValueIsAdjusting())
{
JTabbedPane tabbedPane = new JTabbedPane();
this.jPanel1.removeAll(); // REMOVE ALL DATA IN PANEL TO RELOAD NEW TAB PANEL IN LOOP
String lines[] = loaded_data.split("\\r?\\n");
for (String item : lines)
{
String pattern = "AP.*";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(item);
JPanel panel = new JPanel();
if (m.find())
{
String ap_data = m.group(0);
String[] ap_data_array = ap_data.split("\\|", -1);
if (ap_data_array[0].equals("AP"))
{
JList source = (JList)evt.getSource();
String selected = source.getSelectedValue().toString();
// type selected
if (ap_data_array[1].equals(selected))
{
String tab_name = ap_data_array[2]; // STRING "Tab 1" and "Tab 2" loop
this.jPanel1.add(tabbedPane, BorderLayout.CENTER);
tabbedPane.add(tab_name, new JLabel(tab_name));
tabbedPane.setBounds(0, 0, 530, 500);
this.jPanel1.setSize(530,500);
}
}
}
}
}
}
If I understand your code correctly (no guarantee since it's not a minimal example program that I can run and test), inside of the for loop you're creating a new JTabbedPane with each iteration, adding a single tab to it, and then adding it to a BorderLayout-using JPanel in the BorderLayout.CENTER position. Thus if you iterate twice, you will create two JTabbedPanes, each with only one tab, and the second one will completely cover the first one. If this is indeed the source of your problems then the solution is easy: create only one JTabbedPane, do this before the for loop, and add your tabs (JPanels) inside the for loop.
Other problems include your use of setBounds(...). Don't do this.

Printing all content of a JList as output

I have a JList in my GUI, which uses an ArrayList as data:
ArrayList Cruise = new ArrayList();
Cruise.add("Scottish to Greek Waters");
Cruise.add("Greek to Scottish Waters");
JScrollPane scrollPane = new JScrollPane();
CruiseList = new JList(Cruise.toArray());
CruiseList.setPreferredSize(new Dimension(200, 200));
scrollPane.setViewportView(CruiseList);
CruiseList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
CruiseList.setSelectedIndex(0);
CruiseList.setVisibleRowCount(6);
listPanel.add(scrollPane);
Frame1.setVisible(true);
I have a button - List all Cruises, which once clicked on should display this as output:
"Scottish to Greek Waters"
"Greek to Scottish Waters"
However, upon clicking the button, it only displays the selected list option as output.
This is what I have so far:
listallCruises.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String AllCruises = CruiseList.getSelectedValue().toString();
System.out.print("All Cruises:\n" + AllCruises + CruiseList.getModel() + "\n");
}
});
How do I print out all element in the list upon clicking the button?
You are outputting just the selected value because that's the method you are calling, getSelectedValue().
To display ALL the values, you have to get the model and iterate through the values, like so:
int size = CruiseList.getModel().getSize();
StringBuilder allCruises = new StringBuilder("All cruises:");
for(int i = 0; i < size; i++) {
allCruises.append("\n").append(CruiseList.getModel().getElementAt(i));
}
System.out.print(allCruises);

New line using JLabel and java variable from ArrayList

I create a button that will onclick show in a separate window (like you see below) the list of all users from my database.
But, they are displayed all in one line! Even though I put /n - it just wont work. I mean, it work in console when I use Sys.out but when I go to the Window and put it there it is all in one line :(
What should I change in order to display all of the users one below another.
public class ViewAll {
private String listax = "";
ViewAll() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException{
ArrayList<String[]> allUsers = DbBroker.getArray("select * from user");
for(String[] usr : allUsers)
listax += usr[0] + ")" + usr[1] + ", " + usr[2] + ", " + usr[3] + "\n";
}
public void display() {
JFrame lis = new JFrame("List of all users");
lis.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
lis.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel pane = new JPanel(new GridLayout(0,1));
lis.add(pane);
pane.add(new JLabel("This is the complete list of all users in my db: "));
pane.add(new JLabel(listax));
lis.pack();
lis.setSize(500,400);
lis.setVisible(true);
}}
I suggest that you don't use a JLabel but instead use a JList. It was built to do just this sort of a thing. The key here being: use the right tool for the job. It also appears that you're trying to use a JFrame in a dialog capacity, and if so, don't -- use a JDialog instead, or even a JOptionPane:
public void display(List<String> userList) {
DefaultListModel<String> listModel = new DefaultListModel<String>();
for (String user : userList) {
listModel.addElement(user);
}
JList<String> userLabel = new JList<String>(listModel);
JScrollPane scrollPane = new JScrollPane(userLabel);
String title = "This is the complete list of all users in my db:";
// mainJFrame is the main JFrame for the GUI
JOptionPane.showMessageOption(mainJFrame, scrollPane, title,
JOptionPane.PLAIN_MESSAGE);
}

A JFormattedTextField to accept a currency format without decimals

How do I code a JFormattedTextField to accept a currency format without decimals?
I have tried looking for my answer everywhere. Here, Oracle, Google, and Code Ranch to be specific.
My question: How do I code a formatted text field to accept a currency format without decimals. The text field can accept a value anywhere from $5 to $10,000,000. I would like it to include the "," when need. This field will not be used for mathematical expressions so there is no need to convert it from a string.
Here is the code that I am trying to use. This format is not allowing me to enter any digits at all in the formatted text field.
buildInfo method
//The buildInfo method will build the info panel
private void buildInfo()
{
info = new JPanel();
GridLayout gl = new GridLayout (3,1);
info.setLayout (gl);
//Create panel, label, and text area for pledgers name
p1 = new JPanel();
p1.setLayout(new FlowLayout(FlowLayout.LEFT));
label1 = new JLabel ("Pledger's Name: ");
p1.add (label1);
text1 = new JTextField (20);
p1.add (text1);
//Create panel, label, and text area for pledge amount
p2 = new JPanel();
p2.setLayout(new FlowLayout(FlowLayout.LEFT));
label2 = new JLabel ("Pledged Amount: ");
p2.add (label2);
NumberFormat amount = NumberFormat.getCurrencyInstance(Locale.US);
amount.setMaximumFractionDigits(0);
NumberFormatter pAmount = new NumberFormatter(amount);
pAmount.setMinimum(5.0);
pAmount.setMaximum(10000000.0);
pAmount.setAllowsInvalid(false);
text2 = new JFormattedTextField (pAmount);
text2.setColumns(12);
p2.add (text2);
//Create panel, label, and text area for charity being pledged
p3 = new JPanel();
p3.setLayout(new FlowLayout(FlowLayout.LEFT));
label3 = new JLabel ("Charity Pledged To:");
p3.add (label3);
text3 = new JTextField (20);
p3.add (text3);
//Add panels to main panel
add(p1);
add(p2);
add(p3);
}
Use
NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
format.setMaximumFractionDigits(0);
NumberFormatter formatter = new NumberFormatter(format);
formatter.setMinimum(5.0);
formatter.setMaximum(10000000.0);
formatter.setAllowsInvalid(false);
formatter.setOverwriteMode(true);
JFormattedTextField field = new JFormattedTextField(formatter);
field.setValue(5.0);

Categories