JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

In all your catch blocks call printStackTrace() to get full info on the exact error.

Use System Properties to get the user's home or working dir, and use that for your file(s). It works appropriately in all supported OSs https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

generate random numbers from 1 to 25 and the second random numbers to generate from 2 to 9 and of which the first number must be divisible by the second numbers.

One approach is trial and error - easy to code but inefficient in execution (not a problem with these values, but does not scale well)

do
    generate both random numbers
while (their modulo is not zero)

another way is to generate the second random number (2-9) and a random multiplyer (1- 25/firstnumber) . Mutliply those together to get the first number. This will always work first time.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If x is exactly divisible by y then that means x modulo y must be zero (ie the remainder is zero). Java uses the % operator for modulo

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No. new File(...) does not do anything at the system level, it just creates a Java File object, and therefore can't throw I/O related exceptions. It's not until you try to use that file that any system file activity happens and exceptions can be thrown.

The other three errors are self-explanatory.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Lines 1-4 of your code set up the random data.
Lines 7-21 do the sort and report the timing

So repeat lines 7-21, but don't repeat lines 1-4

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Create the random data
run the sort and see how long it takes
now run the sort again - this time the data will already be sorted - and see how much quicker that is

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

How big do you see this file getting? If it will always fit in memory (say just a few hundred meg) then you can do all the appending editing or whatever in memory and re-write the whole thing at shutdown (and at regular intervals). You can get an awful lot of text in 100Meg - even at a skilled typist's 10 char/second that's like a year of non-stop 40 hours a week typing :)

If its going to be too big and you don't need to edit existing data use a sequential file in append mode. In any case if its just text then why use object serialisation? Just write the text.
If its too big and you want editing you could use a random access file and overwrite the old entry with a deleted flag, then append the revised entry, but personally i would consider a proper database.

But suppose you want to tag entries with some meta-data (date created, language, source URL, keywords etc etc)? In memory its still easy, just create an Entry class with appropriate attributes. But if its too big you definitely need a proper database.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

[edit] ; see invisal's post below for a better explanation of loop problem

100000.0 is a double constant, so the aithmetic is done in double precision, then you assign it to a float and potetially loose precision. Nowdays there's no real reason to use float ever - the precision is rubbish and its no faster than double ona 64 bit processos

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The "enhanced" for loop is generally considered eaier to read and harder to get wrong. but it's up to you.

The thing with method signatures is that ideally a Java programmer should be able to make sense of a call just from by reading it. If there is a comment that should explain why you are making that call now, not what the call does.

Without studying your code in detail I get the feeling that you coculd combine "processString" (what does that mean???) and "mapWords" into a single method maybe something like

void parseAndCountTokens(String tokens) {
    // cleans up tokens, splits on blanks, increments counts in token map mp
    ...
} 

although personally I hate methods that work by hidden side effects (changes mp but mp does not appear in the method signature), so I would probably go the whole hog and make things explicit, eg

    void parseAndCountTokensIntoMap(String tokens, Map<String, Integer> map) {
        // cleans up tokens, splits on blanks, increments counts in token map 
        ...
    } 

Yes, that's a long method name, but it's better than a short name plus a long comment!

(of course, all this is just my opinion)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

In my opinion you should not make a window any bigger than it needs to be unless it's modal and must be noticed. You cannot know what else the user is doing, and what other windows may be competing for his screen space. Things like "full width" are a real no-no when you realise that Mac users in professional environemnts may have musltiple 4k screens aligned horizontally side-by-side.

Apart from that, re

    public void mapWords(){
        for(int i = 0; i < tokens.length; i++){
            if(mp.containsKey(tokens[i])){
                //increment Integer
                mp.put(tokens[i], mp.get(tokens[i]) + 1);//add it to the hashmap and increment integer
            } 
            else{
                mp.put(tokens[i],1);//add it to the hashmap
            }
        }
    }

what's wrong with

    public void mapWords(){
        for (string token : tokens) {
             mp.put(token, mp.getOrDefault(token, 0) +1)
        }
    }

... and if a method call needs a comment then you probably want a better name for the method.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Should be. Just try it.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

or default based on ther content

JLabel and JButton set their (preferred?) size to fit the text that's in them when you pack().
Sometimes you want to start out with them empty, in which case you can initialise them with a suitable number of blanks to get the size right.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

In GBL each child has a position row/col and a size (in units of rows & cols), so if you have something at
(1 ,1, 1, 2 ...
thats position 1,1 one column wide, 2 rows high, ie it occupies rows 1 and 2
so if you don't want to clash with the next child you need to start that at row 3
(1, 3, ...

Sizes are best done in rows/cols/characters etc so Swing can scale the components based on the font size. Text components typically have constructors or set methods in chars/lines, or default based on ther content, so they usually work well. You normally only need to specify pixel sizes for non-text components.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That's quite likely. You are replacing low-level procedural code (loops etc) with higher-level declarative code. However, I think you would have to be processing a lot of data for any difference to be significant.
It gets a lot more interesting if you add one word..

list.parallelStream().
     flatMap(x -> x.stream()).
     mapToDouble(x -> x.getAmount()).
     sum();

now Java will use multiple threads to process parts of the data in parallel. Assuming you have multi-cpu hardware this can give you very significant gains, and the code is orders of magnitude easier than splitting it up and running loops in multiple threads yourself.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Welcome to Java 8!

That code seems to have acumulated some extra code, presumably from trial-and-error.

I took your code, added a litte constructor to Order, and set up some test data like this

        List<List<Order>> list = new ArrayList<>();

        List<Order> list1 = new ArrayList<>();
        List<Order> list2 = new ArrayList<>();

        list1.add(new Order(1));
        list2.add(new Order(2));
        list2.add(new Order(3));

        list.add(list1);
        list.add(list2);

now all it needs to sum all the amounts is to flatten the nested lists, convert the Orders to amounts, and sum them...

list.stream().
     flatMap(x -> x.stream()).
     mapToDouble(x -> x.getAmount()).
     sum();
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi, it's me again (still on the road, so no JDK to check things).
There's no need for extra panels to do this in gbl.
Looking at the code again I see you set the height of your buttons to 2, which would imply you want them to overlap with whatever is below. But then you set the height of the bottom text area to 3, so maybe you have misunderstood the use of width/height parameters?

Setting the size of the window is a problem. The whole idea of layout managers is to fit the contents, allowing for the current system's font sizes, screen resolution etc. You may think 900x800 pixels looks good on your screen, but what happens if someone runs it on a smartphone or a retina Mac? And what happens when the user resizes it?
Set the preferred/ min sizes of each component if you don't like the defaults, but then let the layout manger do its job.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I don't have a JDK here, but if I remember right you are setting the weights to 1 for the text areas and 0 for the buttons, so all the available space is allocated to the areas

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

If you want that level of control over format then inwouldcrecommend gbl

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Ok
As for gridbaglayout, yes I use it when I need exact or complex layouts, but I still use border + grid or box or flow + nested panels for simple stuff. Don't make it any more complex than it needs to be.
No, you don't need to do a console app. Write your application logic in stand-alone classes/methods then simply hard-code some test cases by calling those methods from a main with suitable data values. Keep that test code do you can run the tests again after you enhance or fix the application logic
I usually have a main method in any top level class I write, and it contains an assortment of test/demo calls for the public methods in that class. I use that to ensure its working before I try to integrate it with other classes, and for regression testing after changes. It also serves as a quick example of how to use that class!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, that's exactly right.
We do try to give hints rather than solutions because that's how people learn. But if anything is too cryptic then please ask for clarification.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You ignored the problem I told you about.
There are two textInput variables, declared on lines 24 and 40 in the previous code.
The first one is used throughout the class, but the second one is the one you initialise.
All the other stuff you changed will not fix that problem. You really must spend more time reading our replies carefully, thinking about them, and asking questions if there is something you still don't understand.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Null pointer exception.... Uninitialised variable.
Look at the line it refers to. The only var it could be is textInput.
Why is it null?
You declare it on line 24 but you never initialise it
You may think that line 40 does that, but it just initialises a local var with the same name.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Hi Taywin. Yes, I know the language is the same, but the API is different, especially around program initialisation and the gui. I didn't want to make any assumptions that could send the op down some invalid side track, that's all.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I don't know android Java, but are you sure isEmpty() will be true if the field contains a blank character as opposed to no character st all?

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

mp is a map of strings to integers, so the arithmetic works on the values correctly. tokens is a string, but the value you are adding to is mp.get(tokens[i]), which is the integer value

With java 8 you can simplify the code with a getOrDefault that will give you a default value of 0 if there is no entry for that key...

Mp.put(key, mp.getOrDefault(key, 0) +1))

No need to have an if test for whether the entry exists or not.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Anonymous classes are good if they are small, but if they are more than few lines the code gets hard to read, in which case a named inner class is better. (See how I avoided mentioning lambdas there?).

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You need that class (exactly the same version) on both machines.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Seems like the server is running on a machine that does not have that class in its classpath

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Line 9 ( ) is not the same as [ ]

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Insets work well, but the whole set minimum/maximum/preferred size, along with setSize itself is a nightmare. Different layout managers respect or ignore any or all of those depending on the phase of the moon or the presence/absence of a black cat in the room. Trial and error seems the only way.
Personally I just use GridBagLayout which is tedious but respects the settings you give it.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Key released - the value in your theChar is useless if you get a sequence like the one in my last post. The code at the end of your post is the way to do it.

Your keyTyped is still far too complicated. Just get the Unicode char (NOT the VK constant) event.getKeyChar() and add it to the text area. That's all. One line of code. I guess you didn't read my previous posts too closely (sigh).

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

That code won't handle modifier keys (shift etc) correctly, and there's no quick fix for that. The only sensible way to get the correct character displayed is to use the KEY-TYPED event. It's also trivially easy. Forget the switch etc.

There are no guarantees about the order in which events will be delivered, so if you press/relase 2 keys quickly you MAY get
key1 pressed
key2 pressed
key1 released
key2 released
... in which case your existing code will lose track of which button. You need to use the VK in the key released event to know which key to un-highlight.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I think you mean setFocusable, not isFocusable

Your proposed solution is almost OK except you missed the whole point about key pressed vs key typed for the char that you will display.

Trying to control the focus is hard, and usually fails becuase the user can change it at will. You can add the same key listener to every component in your window, and then not worry about which had the focus.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I think I may have said right a the beginning - Swing keyboard handing is surprisingly hard, mostly because you need to know where the keyboard focus will be, (because that's where you need to add your listener). If your text area is responding to keyboard input, then it's the component that has the focus, so that's the component you need to add the listener to. But even then, if the use clicks somewhere else that may change the focus.
See https://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
for more info on this topic.

There is a solution to the focus problem... see http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The pressed and released events give you a VK wich is a reference to a physical key on the keyboard. You can use those (via getKeyCode, not extended key code) for the map lookup to get the corresponding button. That's not the same as the typed event that gives you an actual Unicode character.
Those VKs are useless to you in updating the text area, anlthough they are the ones you need to highlight the key button on the screen. The chars in KEY_TYPED are useless to you in highlighting buttons, although they are the ones you need to add to the text area.

If that's stuill confusing, just think about an sequence like

press shift
press 8
release 8
release shift

The pressed/released events give you the VKs for the shift and 8 keys to highlight and unhighlight, but its the typed event generated in the middle of that sequence that gives you the asterisk to display in the text area

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

IF you really do have a lot of drawing that is repeated without being changed and if that is consuming a significant amout of resources, then yes, there MAY be an advantage in pre-rendering it.
If so, just create a BufferedImage, and call its createGraphics() to get a Graphics2D that allows you to use your existing drawing code to draw directly to the BufferedImage.

.. but we've spoken before about premature optimisation... ;) J

Doogledude123 commented: yes, we did :P +3
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

pack() before making visible to avoid a flickery repaint.

You are confusing parent and child layouts. Every container has a layout that controls how its contents are layed out, but has nothing to do with how that containier is placed in its parent.

So its the frame's layout that positions the panel at the bottom, and the panel's layout that positions the rows insde that panel. Border layout for the frame is OK, grid layout for the panel is OK.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Your keys panel has a border layout, so you are adding all the rows in the same place, but you want the rows inside it stacked vertically.
I can't see where you pack()the frame after adding everything.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

No need to search the map - that's what maps do - lookup values by their keys.
You can just get the button directly from the map given the key code

JButton buttonToHighlight = myMap.get(clickedKeyVal);

ps: Better to declare the map as <Integer, JButton> rather than <Integer, Object> so the compiler knows you don't need to cast the retrieved obj to JButton

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

You can't use the VK constants from another class without either
fully qualifying them:
java.awt.event.KeyEvent.VK_1
or (better) by importing all the static public names from that class
import static java.awt.event.KeyEvent.*;
then you can just use VK_1 etc

Your little method has to return the button it creates if you want to add that to a panel.
If the method is void then
row1.add(createButton(VK_DEAD_TILDE, "~"));
wil fail because createButton(VK_DEAD_TILDE, "~") doesn;t return anything to add

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, the VK_ constants are the ones that refer to buttons on a keyboard. They're the ones you need.
mp.put(new Integer(xxx), row1.add(new JButton("~")));
You don't need the new Integer because Java "boxing" will automatically convert an int to an Integer.
You can't use row1.add in there because add does not return a value, and anyway you don't want another new button there because you want to use the one you already created in your map.
Plese go back a couple of posts and perhaps now it will be clearer why I suggested a little method to create the button, add it to the map, amd return it ready for adding to a row. Only now you will want to use the key code as well so it looks more like
row2.add(createButton(VK_Q, '"Q");

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

The integer values you need for the keys are those defined in the KeyEvent class. Otherwize looks OK so far.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Yes, yes and yes

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

A good example of why you shou;dn't start with the GUI details!
Think about the heart of the program. When the user types a key you want to make changes to the corresponding button. That implies you will have some kind of Map with keyboard chars as key and buttons as data. You can use that map to get the button to change its colour or whatever without knowing anything about where it is on the screen.
So there's no need for any other arrays to hold the buttons.
You are going to have to create and place 40-odd buttons one way or another, and because there's no logic to how the keyboard is layed out, there's no way to automate it.
All you can do is use a small method or two to eliminate repeated code. For example

JButton createButton(char letter) {
    create a JButton, set its text to letter, add it to the map with letter as its key
 }

so then you can

 row2.add(createButton('Q'));
 row2.add(createButton('W'));
 etc

ps when I say char I probably mean some kind of Key Code to allow for backspace, shift etc)

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Given that the buttons don't actually do anything, or have any data associated with them, I can't see any need for anything more than a vanilla JButton. Oh well, I guess the previous discussions were useless for this particular exercise, but maybe added to your understanding of some wider issues?

Responding to the keyboard in the simple way is a surprisingly hazardous thing - in particular watch out for which component has the keyboard focus at any given time.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

OK - I thought the idea was to be able to type on the screen? If it's not going to respond to touches then why use JButtons? Anyway - to answer your specific questions:

2 chars:
each key can generate 2 possible letters - upper/lower case alpha, or 8 vs asterisk etc - selected by the shift key.

extends JButton implements ActionListener
It's a specialised JButton - all the usual JButton stuff plus stuff specific to typewriter keys, so extending JButton. Implementing the action listener in the same object makes the code easy - no need to test which button was pressed, and all the other info about that key is already present.

Constructors.
Because keys vary in width there's a constructor that has an explicit width parameter in addition to the two chars. Because most keys are the same width there's a convenience constructor that just has the chars and sets the width to a default value. It does that by calling the other constructor, passing a default value for the width. In this context this refers to a constructor of the same class

addActionListener(this)
this is the current object (instance of KeyButton).

The KeyButton class represents a single typewriter key, with all its associated data and event handling. It's a kind of JButton so you can use it directly in a GUI.
You would create them in the Keyboard class's constructor, something like:

...
row2.add(new KeyButton('q', 'Q'));
row2.add(new KeyButton('w'.,'W'));
...
row4.add(new KeyButton(' ', ' …
JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

I would create a class, something like...

class KeyButton extends JButton implements ActionListener {
  char normalChar, shiftedChar;
  int width;
  static int HEIGHT = 20, DEFAULT_WIDTH=20;
  public KeyButton( char normalChar, char shiftedChar) {
      this(normalChar, shiftedChar, DEFAULT_WIDTH);
   }
  public KeyButton( char normalChar, char shiftedChar, int width) {
      ...
      addActionListener(this);
   }
  public void ActionPerformed( etc ) {
     // tell whoever that the letter was typed (interesting design qiestion)
  }

then I would have a KeyBoard class that extends JPanel and adds all the KeyButtons to itself as discussed earlier. Shift key is a special case, also interesting design decision!

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Thinking about this a bit more...
it's a very interesting exercise. As soon as you think about the modifier key(s) it has great scope for good or bad design. It's small enough that a bad design will work OK, but just big enough to be a great learning project for better design.
If you start with laying out the GUI, then add the action listeners, you are almost guaranteed a huge pile of spaghetti code in the end.
If you start with some classes with their responibilities and public interfaces then you could end up with a demonstration-quality design based on principles that scale to larger systems. It's up to you, of course.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

so rather than GridBagLayout, do you think that GridLayout is a better idea?

Apart from rows 2/3 the keys do not line up vertically, so the whole thing is not a grid. I would just flow each row along a panel, with the 4 panels stacked vertically (see jwenting above)

when you say "add it directly", do you mean to add it directly to the JFrame with no intermediate panel?

Yes. the intermediate panel gains you nothing execept some unnecessary code and bit of unnecessary run time overhead.

JamesCherrill 4,733 Most Valuable Poster Team Colleague Featured Poster

Looks reasonable to me - except I don't see why you have a panel (line 5) with only one thing in it - just add the text area directly.

For the event handlers on those keys you will DEFINITELY want to use the parametised handler technique from your previous project.

Looking at the first two rows of keys you do not want to try to do that with just a GridBagLayout!