Search code examples
javaswingjframejpanelborder-layout

creating JFrame with variable amount of JLabels


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


Solution

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