Jump to content

Learning Curve


BrainDeadGenius

Recommended Posts

I'm using NetBeans (for the GUI developer) to do some Java / GUI work.

I've been trying to add content (via Map<String>) to a jPanel on a jTabbedPane. I want to add a jLabel (key) with a jTextField (value) for each item present in the Map<string>. 

 

With a button click, this is what I've been able to get, and it almost works. There's two problems.

1) The content appears on the tab, for about 1/3 of a second.

2) If there's more to the Map<string>, it tries to do it on the same line rather than creating a nice flow. Also, if there's too much, how would I be able to make it scrollable?

 

private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        JPanel p = jPanel4;
        p.setLayout(new FlowLayout()); 
        
        for (Object key: passwords.keySet()) {
            JLabel  passwordText = new JLabel((String) key);
            JTextField  passwordField = new JTextField((String) passwords.get(key));
            p.add(passwordText = new JLabel((String) key));
            p.add(passwordField = new JTextField((String) passwords.get(key)));
            add(p);
        }
    } 
Link to comment
Share on other sites

1) Not enough code, and please elaborate a little more on what you mean (when does it appear? is it consistent behavior, as in does it happen every time?)

 

2) Add the panel to a JScrollPane

 

Is there a reason why you're casting so much? Why are you referencing the keySet using the Object type, rather than Set<String>?

Link to comment
Share on other sites

After giving another look, it seems you're trying to add components to an already visible panel. I had a hard time understanding your problem, but forgetting to validate() a container (which is already visible) after adding components to it will result in an empty container:

 

"Layout-related changes, such as setting the bounds of a

component, or adding a component to the container, invalidate

the container automatically"

 

If I'm understanding this correctly, you want to iterate through the entries of a map, and display a label and field for each entry. Here's a little example (which performs what you want) that shows what I'm referring to about validating. Simply uncomment the pack() to make the code below work:

public class Demo {
    public static void main(String[] args) {
        Demo demo = new Demo();
        EventQueue.invokeLater(demo::init);
    }
    
    void init() {
        Map<String, String> map = createMap();
        
        JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(3);
        
        addComponentsTo(frame, map);

        frame.pack();
        frame.setVisible(true);
    }
    
    void addComponentsTo(JFrame frame, Map<String, String> map) {        
        JPanel panel = new JPanel();
        GridLayout layout = new GridLayout(0, 2);
        layout.setHgap(0);
        panel.setLayout(layout);
        
        JButton button = new JButton("...");
        button.addActionListener(event -> {
            map.forEach((key, value) -> {
                JLabel label = new JLabel(key);
                JTextField field = new JTextField(value);
                panel.add(label);
                panel.add(field);
                //frame.pack();
            });
        });

        frame.add(button);
        frame.add(panel);
    }
    
    Map<String, String> createMap() {
        Map<String, String> map = new TreeMap<>();
        map.put("First", "FirstItem");
        map.put("Second", "SecondItem");
        map.put("Third", "ThirdItem");
        
        return map;
    }
}

I used a TreeMap to retain order in the map. Although "validate()" will display the items, it will not size the frame to fit them. You should instead "pack()" as I did, which validates the entire component hierarchy.

Link to comment
Share on other sites

I'll take a look at how that works tomorrow as I'll be headed off to bed soon. I did try and play around with map, but I realized it didn't save the contents "indefinitely". IE, you could start the .jar and load the contents of map you saved during a previous session. I'm using a text file to do such now, but it's not really a proper way to do it. What do you have for suggestions for that? I've shown my code over at this thread:

http://osbot.org/forum/topic/78630-random-password-generator/

 

And could you give suggestions on how to make it look / work better? (Not just changing the colors of the backgrounds / fonts)

Link to comment
Share on other sites

I'll take a look at how that works tomorrow as I'll be headed off to bed soon. I did try and play around with map, but I realized it didn't save the contents "indefinitely". IE, you could start the .jar and load the contents of map you saved during a previous session. I'm using a text file to do such now, but it's not really a proper way to do it. What do you have for suggestions for that? I've shown my code over at this thread:

http://osbot.org/forum/topic/78630-random-password-generator/

And could you give suggestions on how to make it look / work better? (Not just changing the colors of the backgrounds / fonts)

Sounds like a job for serialization (preserve the state of an object after shutdown). Create an ObjectOutputStream and call writeObject, passing in the map as the parameter. You can then read it back in using an ObjectInputStream. This will prevent the need to read text from a file as you currently are.

I'm not at a computer, so I can't run your app. But looking at the code, there are a few things you should do:

1.

while (x < SliderT) {
    randomNum = rand.nextInt(random.length());
    password += random.substring(randomNum, (randomNum + 1));
    x++;
}

You should be using a StringBuilder for password. Right now, you are using String concatenation, which actually uses a StringBuilder under the hood (view the bytecode). The problem is, each time you do "+=", a new StringBuilder is created, which means you are creating a bunch of excess objects which may impact performance. You should instead do:

StringBuilder password = new StringBuilder();

while(...) {
    ...
    password.append(random.substring(...));
    ...
}

2.

Boolean Button1, Button3, Button4, Button5;

Button1 = jToggleButton1.isSelected();
Button3 = jToggleButton3.isSelected();
Button4 = jToggleButton4.isSelected();
Button5 = jToggleButton5.isSelected();

I'd usually ask why you are declaring and assigning in different locations, but there is a bigger problem here: autoboxing.

 

Unless this code was being called within a long running loop, it doesn't matter as much. But there's still no reason why you should be doing it. Don't use the Boolean reference type, use the boolean primitive type. Otherwise, you're basically doing

Button5 = new Boolean(...);

Creating excess objects that aren't needed. You would also be able to finally do if(!Button5) rather than if(Button5 == false).

 

3.

if(jToggleButton4.isSelected()){
    jToggleButton4.setText("ON");
} else {
    jToggleButton4.setText("OFF");
}

Use a ternary:

String text = jToggleButton4.isSelected() ? "ON" : "OFF";
jToggleButton4.setText(text);

4. Try to go through an replace all ActionListener anonymous classes with lambda expressions. This will reduce the amount of class files generated, reducing the amount of files needed to be loaded by a classloader.

 

5. 

p.removeAll();
p.repaint();

This shows me you have yet to understand the component system Swing provides you. I highly suggest taking a deeper look into it. You need to revalidate after affecting the component hierarchy (add/remove), not repaint.

 

There are a few other things I wanted to note down, but my phone is dying so I'ma have to come back to this. If you'd like me to post this on your code thread, let me know and I'll transfer it over.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...