1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Development Random.jar

Discussion in 'Software' started by Edge102030, 26 May 2011.

  1. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    Hey guys, I made a program called random.jar for a friend who wanted something simple that could produce secure passwords and here's the result:
    [​IMG]

    Code:
    package random;
    
    import java.util.logging.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.*;
    import java.util.Random;
    
    
    public class Jarv extends JFrame implements ActionListener, Runnable {
        
        // declare the random object for use later    
        Random r = new Random();
        // declare the thread for running later
        Thread t;
        // declare variables for use in the thread
        String alphabetChar = "";
        StringBuffer outputStr = new StringBuffer("");
    
        // build text box
            JTextField strOutput = new JTextField();
            JTextField strLength = new JTextField();
            JLabel StrLengthLabel = new JLabel(" String Length: ");
            
    
            public Jarv() {
    
            // basic window stuff
            super("Random");
            setSize(200, 105);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                   
    
            // panel (layout) for the label and text boxes
            JPanel textPanel = new JPanel();
            BorderLayout bb = new BorderLayout();
            textPanel.setLayout(bb);
            textPanel.add("West", StrLengthLabel);
            textPanel.add("Center", strLength);
            textPanel.add("South", strOutput);
            
    
            // make button, add listener, and do panel
            JPanel buttonPanel = new JPanel();
            BorderLayout db = new BorderLayout();
            JButton runButton = new JButton("Make String");
            runButton.addActionListener(this);
            buttonPanel.setLayout(db);
            buttonPanel.add("South", runButton);
            
            
            // make checkbox, add to panel
            JPanel groupPanel = new JPanel();
            BorderLayout xb = new BorderLayout();
            groupPanel.setLayout(xb);
            groupPanel.add("Center", textPanel);
            groupPanel.add("South", buttonPanel);
            
            // layout
            BorderLayout flo = new BorderLayout();
            setLayout(flo);
            add("Center", groupPanel);
            strLength.setText("6");
            setVisible(true);
    
        }
            
    
    
    // thread
        public void run() {
            
    // clear the output variables 
        alphabetChar = "";
        outputStr.delete(0, outputStr.length()); 
    
        
        
    
        // begin random string creation loop
        for (int idx = 0; idx < Integer.parseInt(strLength.getText()); ++idx){
    
        // begin code if nextboolean is chosen as true
        if (r.nextBoolean() == true) {
    
            // do alpha-numeric translation
            switch (r.nextInt(26)) {
                case 0: alphabetChar = "a";  break;
                case 1: alphabetChar = "b";  break;
                case 2: alphabetChar = "c";  break;
                case 3: alphabetChar = "d";  break;
                case 4: alphabetChar = "e";  break;
                case 5: alphabetChar = "f";  break;
                case 6: alphabetChar = "g";  break;
                case 7: alphabetChar = "h";  break;
                case 8: alphabetChar = "i";  break;
                case 9: alphabetChar = "j";  break;
                case 10: alphabetChar = "k";  break;
                case 11: alphabetChar = "l";  break;
                case 12: alphabetChar = "m";  break;
                case 13: alphabetChar = "n";  break;
                case 14: alphabetChar = "o";  break;
                case 15: alphabetChar = "p";  break;
                case 16: alphabetChar = "q";  break;
                case 17: alphabetChar = "r";  break;
                case 18: alphabetChar = "s";  break;
                case 19: alphabetChar = "t";  break;
                case 20: alphabetChar = "u";  break;
                case 21: alphabetChar = "v";  break;
                case 22: alphabetChar = "w";  break;
                case 23: alphabetChar = "x";  break;
                case 24: alphabetChar = "y";  break;
                case 25: alphabetChar = "z";  break;
    
            }
    // if r gave a true value earlier then capitalise the alphabetChar
    // variable
    
            if (r.nextBoolean() == true) {
                alphabetChar = alphabetChar.toUpperCase();
    
            }
    // if r gave a false earlier then make a random number 0-9 and store
    // it in the relevant array slot
        } else {
                alphabetChar = Integer.toString(r.nextInt(10));
            }
        outputStr.append(alphabetChar);
    
        }
        // set the random string output field to the string created by the thread        
        strOutput.setText((outputStr.toString()));
            
        }
        
        // method activated by the button (listener)
    public void actionPerformed(ActionEvent event) {
        
    
        // run the thread
        
        new Thread(this).start();
        
        }
        
        
        // run the Main() class
    public static void main(String[] args) {
    
         Jarv m = new Jarv();
    
    }
    }
    


    Rapidshare: linky

    I wanted to ask you guys if i've made any blunders or if bits of my code can be optimized further. Feel free to make comments.

    EDIT: Source code and rapidshare have now been updated due to massive improvements through the use of stringbuffer and correct application of threading.
     
    Last edited: 26 May 2011
  2. Cleggmeister

    Cleggmeister Of reasonable knowledge...

    Joined:
    12 Oct 2009
    Posts:
    1,140
    Likes Received:
    22
    Not sure about the code, but my friend and I had a protracted row about whether a computer could actually generate a genuine random number. We eventually agreed, after lots of booze, that it couldn't. :)
     
  3. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    Ahh yes, sorry - it's pseudo-random :)
     
  4. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    your using run() wrong...
    which seems like an odd thing to say about a function I know

    by calling run() directly, it is executing in the same thread
    if you want to start a new thread you need to have something like:
    new Thread (this).start();

    i'm not 100% sure on that... and it looks a bit ugly too
    but if it runs in its own thread you probably wont need to "limit the cpu" by sleeping


    also string concatenation is bad
    think about using a StringBuffer/StringBuilder
     
  5. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    The sleeping is just to spread out the cpu usage over a longer period.

    Would you mind giving a small example of how to have the extra thread run please?

    I'm going to go look up what concatenation is now :) Bit of a programming newbie.
     
  6. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    again im not 100% sure on the validity on the below, so you'll have to try it
    with different threads, your computer should be able to stop the run function using up loads of cpu

    Code:
        
    // method activated by the button (listener)
    public void actionPerformed(ActionEvent event) {
        
        //ive removed your cpuVar stuff, but if you want it, put it back
    
        // run the thread
        new Thread(this).start();
        
    }
    
    i would also make outputStr, and alphabetChar local to run()
    they arent used outside it, and with new threads, you'll likely want separate variables for each


    *Edit*
    Concatenation is putting two things together
    e.g.
    String str = "a";
    str += "b";
    str = str + "c";

    In java, you cant change Strings, so what it is actually doing, is making its own StringBuffer, appending a character, then changing that back to a string every time
     
    Edge102030 likes this.
  7. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    Tyvm plugs :D, i first implemented the stringbuffer like so:

    (Snippets)
    Code:
        (constructor)
        // declare variables for use in the thread
        String alphabetChar = "";
        StringBuffer outputStr = new StringBuffer("");
    
        (run function)
       // clear the output variables 
        alphabetChar = "";
        outputStr.delete(0, outputStr.length()); 
    
    
        outputStr.append(alphabetChar);
    
        }
        // set the random string output field to the string created by the thread        
        strOutput.setText((outputStr.toString()));
            
    
    I then corrected the event code for running a thread as you suggested :) and the program is one hell of a lot snappier now, before the mouse down visual would hold as the run() function was executed (about a minute or so for a 111111 length string) now the animation is as it should be and it can do a 9999999 length string in about 9 seconds.

    +rep to your sir!!
     
  8. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    no prob
    also remember that sleep(1) means sleep for 1millisecond (0.001s)
    0.001 * 111111 = 111.111 seconds

    that might account for your speed gain ;)
     
  9. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    It only does the sleep when you tick the limit checkbox (that was more of an experiment), i think the real gain was using a stringbuffer :D, will definitely be using those in the future.
     
  10. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    Ah, well the mouse behaving normally is likely due to it being on a different thread to the GUI

    also, if you click the button twice, your string will be longer than you expect, even though you reset it (because both threads will be adding characters to the same buffer)
     
  11. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    Any way to make it only ever run one extra thread? I've been experimenting and can't seem to figure it out.
     
  12. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    you can always disable the button at the beginning of the actionPerformed function

    then get the run() function to enable it

    will have to make the button a member of your class
    //to disable
    runButton.setEnabled(false);
     
  13. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    Hmm, some of that massive speed boost seems to be perceived. A 9999999 length string causes too much memory to be used, and a 9199999 length string takes far longer than it appears to and continually adds to the textbox for some reason, instead of making the string and swapping it into the textbox.


    Edit: with 7 digit string lengths i start to get out of memory errors.

    The button event code now looks like this:

    // method activated by the button (listener)
    public void actionPerformed(ActionEvent event) {

    new Thread(this).start();
    runButton.setEnabled(false);


    }

    and on the end of the run() function is this:
    runButton.setEnabled(true);
     
    Last edited: 26 May 2011
  14. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    it might be a case the GUI can't keep up...
    try printing a string that is a million characters long to the console, and it will take a while

    if you are getting exceptions throw for the memory, you can increase the amount of memory the virtual machine uses

    assuming it is the GUI...
    if you really need strings that long, and need to copy them, it might be best to put it into a file


    *edit*
    just ran your code, and its only slow went I try to move to the end of the output textfield (using the End button)
    so GUI definitely seems the culprit
     
    Last edited: 26 May 2011
  15. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    I'm thinking the memory error is the string buffer not being big enough, since the vm size in the debugger never reaches it's max.

    EDIT: That was the problem, fixed it by changing the end of the run() function to this:

    outputStr.append(alphabetChar);

    if (outputStr.length() > 100000) {
    opt = outputStr.toString();
    outputStr.delete(0, outputStr.length());
    }

    }
    // set the random string output field to the string created by the thread
    strOutput.setText((opt + outputStr.toString()));

    opt is a String variable.
     
    Last edited: 26 May 2011
  16. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    and if the string length overall is greater than 2 * 100000, you will overwrite your opt

    that if block will also slow it down somewhat

    to me its cleaner to increase the memory the VM is allowed to use
    or even better, put a maximum on the input size - unless you really need strings this long
     
  17. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    True, i don't need outputs of this size (or anywhere near this size), but it's a learning experience to experiment :D.

    EDIT: it wasn't the vm size, but the maximum amount of data the StringBuffer variable is capable of holding.
     
  18. Plugs

    Plugs Minimodder

    Joined:
    5 Nov 2009
    Posts:
    528
    Likes Received:
    64
    apparently, StringBuffer's size starts off small (you can set it high with the constructor)
    and will keep doubling in size

    up to some limit involving the VM's memory limit
     
  19. Deders

    Deders Modder

    Joined:
    14 Nov 2010
    Posts:
    4,053
    Likes Received:
    106
    Whatever happened to the RND function in BASIC?
     
  20. Edge102030

    Edge102030 Son, i am disappoint.

    Joined:
    21 Aug 2009
    Posts:
    568
    Likes Received:
    28
    This is the full out of memory error:
    Code:
    Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    	at sun.font.GlyphList.ensureCapacity(GlyphList.java:155)
    	at sun.font.GlyphList.setFromChars(GlyphList.java:242)
    	at sun.java2d.pipe.GlyphListPipe.drawChars(GlyphListPipe.java:85)
    	at sun.java2d.pipe.ValidatePipe.drawChars(ValidatePipe.java:160)
    	at sun.java2d.SunGraphics2D.drawChars(SunGraphics2D.java:2843)
    	at sun.swing.SwingUtilities2.drawChars(SwingUtilities2.java:770)
    	at javax.swing.text.Utilities.drawTabbedText(Utilities.java:170)
    	at javax.swing.text.Utilities.drawTabbedText(Utilities.java:89)
    	at javax.swing.text.PlainView.drawUnselectedText(PlainView.java:137)
    	at javax.swing.text.PlainView.drawElement(PlainView.java:96)
    	at javax.swing.text.PlainView.drawLine(PlainView.java:65)
    	at javax.swing.text.PlainView.paint(PlainView.java:288)
    	at javax.swing.text.FieldView.paint(FieldView.java:171)
    	at javax.swing.plaf.basic.BasicTextUI$RootView.paint(BasicTextUI.java:1422)
    	at javax.swing.plaf.basic.BasicTextUI.paintSafely(BasicTextUI.java:722)
    	at javax.swing.plaf.basic.BasicTextUI.paint(BasicTextUI.java:869)
    	at javax.swing.plaf.basic.BasicTextUI.update(BasicTextUI.java:848)
    	at javax.swing.JComponent.paintComponent(JComponent.java:752)
    	at javax.swing.JComponent.paint(JComponent.java:1029)
    	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
    	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
    	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
    	at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
    	at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
    	at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
    	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
    	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
    	at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
    	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:642)
    	at java.awt.EventQueue.access$000(EventQueue.java:85)
    Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    	at sun.font.GlyphList.ensureCapacity(GlyphList.java:155)
    	at sun.font.GlyphList.setFromChars(GlyphList.java:242)
    	at sun.java2d.pipe.GlyphListPipe.drawChars(GlyphListPipe.java:85)
    	at sun.java2d.pipe.ValidatePipe.drawChars(ValidatePipe.java:160)
    	at sun.java2d.SunGraphics2D.drawChars(SunGraphics2D.java:2843)
    	at sun.swing.SwingUtilities2.drawChars(SwingUtilities2.java:770)
    	at javax.swing.text.Utilities.drawTabbedText(Utilities.java:170)
    	at javax.swing.text.Utilities.drawTabbedText(Utilities.java:89)
    	at javax.swing.text.PlainView.drawUnselectedText(PlainView.java:137)
    	at javax.swing.text.PlainView.drawElement(PlainView.java:96)
    	at javax.swing.text.PlainView.drawLine(PlainView.java:65)
    	at javax.swing.text.PlainView.paint(PlainView.java:288)
    	at javax.swing.text.FieldView.paint(FieldView.java:171)
    	at javax.swing.plaf.basic.BasicTextUI$RootView.paint(BasicTextUI.java:1422)
    	at javax.swing.plaf.basic.BasicTextUI.paintSafely(BasicTextUI.java:722)
    	at javax.swing.plaf.basic.BasicTextUI.paint(BasicTextUI.java:869)
    	at javax.swing.plaf.basic.BasicTextUI.update(BasicTextUI.java:848)
    	at javax.swing.JComponent.paintComponent(JComponent.java:752)
    	at javax.swing.JComponent.paint(JComponent.java:1029)
    	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
    	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1479)
    	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1410)
    	at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
    	at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
    	at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
    	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:785)
    	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
    	at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
    	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
    	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:642)
    	at java.awt.EventQueue.access$000(EventQueue.java:85)
    BUILD SUCCESSFUL (total time: 24 seconds)
    
     

Share This Page