Win a copy of Android Programming: The Big Nerd Ranch Guide this week in the Android forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

save a file image from the graphics panel to where the user requires  RSS feed

 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Happy new year to your all,

I wonder if someone can help me with an assignment we have for uni, as I cannot get my head around Java. I have looked at various forums etc.... and spend hours trying to get it to work, but I am still having no luck. The program is for a drawing app.

I just need to set the pen to a starting point of 0,0 in the graphics panel.
To be able to save a file image from the graphics panel to where the user requires.
when the text file is loaded to display an invalid command error on the command that are not valid

i.e move 100 when it should be move 100,200
or text hello when it should be text "hello"

Drawing

instruction

Graphics
 
Knute Snortum
Sheriff
Posts: 3734
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch, Kirk Preston.

It looks like you have a good start.  I would change line 60 in Instructionpanel to look like this:

This says in effect, Split the string on one or more whitespace characters.  This gives more flexibility to your input file.  Do you have a sample input file you could post?
 
Knute Snortum
Sheriff
Posts: 3734
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm seeing a log of code like this in Instructionpanel:

This violates the DRY principle (don't repeat yourself).  What should you do instead?

Whenever you have code like this:

...it is written better like this:

This is so if foo is null it won't throw an exception.
 
Knute Snortum
Sheriff
Posts: 3734
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What happens if the input file just contains this:

?
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks fir the prompt reply to my query

for an valid command file which is stored as a text file(txt)

txt file 1

MOVE 100 200
LINE 300 200
LINE 300 400
LINE 100 400
LINE 100 200

txt file 2

MOVE 300 300
CIRCLE 300
CIRCLE 250
CIRCLE 200
CIRCLE 150
CIRCLE 100
SOLID_CIRCLE 50

txt file 3

MOVE 100 200
COLOUR 255 0 0
TEXT "This is RED text"
MOVE 100 250
COLOUR 0 255 0
TEXT "This is GREEN text"
MOVE 100 300
COLOUR 0 0 255
TEXT "This is BLUE text"

txt file 4

MOVE 100 200
COLOUR 255 0 0
TEXT "This text should not be seen!"
CLEAR
COLOUR 255 255 255
TEXT "This is WHITE text that should be seen!"
MOVE 100 220
COLOUR 0 255 255
LINE 300 220
COLOUR 255 255 0
SOLID_CIRCLE 10
MOVE 100 225
LINE 300 225
CIRCLE 10

txt invalid data

txt file 1

INK 100 200
LINE 300 a
MOVE 300
CIRCLE 100 200
COIRCLE
CIRCLE xyz
CLEAR "hello"
TEXT some invalid text
SOLID_CIRCLE qwerty
MOVE 300.2 200
MOVE 200 300 400
LINE 100
LINE 100 200 300

invalid txt file 2

MOVE 100 200
CIRCLE -10

invalid txt file 3

COLOUR 255 255
COLOUR RGB
COLOUR
COLOR 100 100 200
COLOUR 255 256 255
COLOUR 255 100 x
COLOUR -100 200 100
COLOUR 99 99 -1
COLOUR 200 10.2 20
 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Rather than all those if blocks, have you considered a switch, which can take Strings as its cases?
 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As a general rule, program logic shouldn't be in a GUI application. You shou‍ld have an application that reads the file and can interpret the instructions. Even if all it does it print things like
MOVE 100 200
at this stage.
You can then find a way of throwing errors when you encounter an incorrect entry in a file.
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for everyone's advice

In regards to the switch,  would it be possible to have an example from my code, so I can see the results and how it works?

I have only a week left before the code has to be submitted. When the code is demonstrated, I need to be able to explain the code, so an idiots guide would be great and why it has been done this way

The priorities to me are:-

1:-getting the invalid text commands displaying an error
2:-to be able to draw on the graphic panel
3:-to be able to save the drawing on the graphics panel in png format

If I have any time left, for bonus points,  I would like to be able to print the drawing on the graphics panel + the text commands, save the text commands in txt format, add a few more commands for creating more different shapes, 
 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can read about switch statements in the Java™ Tutorials.
Your methods called from the switch might take a String[] as their parameters; that will allow validation not only of the number of arguments but their types. You can apply each String to a Scanner object, and read about the pros and cons of that technique here. If you fail to read correct input (e.g. colour with only two numbers) you will have to decide what to do. The most defensive approach is to throw an Exception.
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
looking at the switch , does this pseudocode look about right?


                     break;
            case 7: commandString = "COLOUR";

// colour has 3 values between 0-255, if <3 values goto the default, else if the 3 values are between 0-255, else  displays default
                     break;
          
            default: commandString = "Invalid command or format";
                     break;
        }[/code]
 
Knute Snortum
Sheriff
Posts: 3734
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It would be more like
 
Liutauras Vilda
Marshal
Posts: 4141
227
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Another thing or two.

1. Avoid using method name "processFile(File file)". Process file is very vogue term, it can be anything - modify, merge, read, write... Pick some better name for it. Maybe readInstructions(), interpretInstructions(),...?

2. If possible, avoid using File object along with Scanner. Oracle pointed out some flaws in this combination in certain scenarios. So, better is to use Path object. i.e.:
or if you're forced to have a parameter File, then inside that method consider doing:

3. I think you need to be more consistent on braces placing style. At the moment I can see at least 3 different styles.

4. Two problems here. First - what this '3' below mean? No need to answer, but rather consider assigning it to something with a reasonable name, i.e.: expectedParameters. Second - why comment says check if there are two parameters, but actually checking if there are 3?
There is only one thing which is worse than non informative comment - is misleading comment.

5. returnString +=... consider using StringBuilder instead. Read documentation why. Hint: String is an immutable class, so every time you concatenate something, you create a new (not always true, but think it is) String object.

6. command.equals("COLOUR") it seems program is not meant to be created for US market, no worries for that, that was more of a puzzle
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well spotted on the comment, I'll alter this in my code. I have just been concentrating on trying to get the code to work.

The three is referring to a command, and that it should have three parts i.e move 100 200. The array has been split using the space to split, so move would be in index 0, integer x would be in index 1 and integer Y in index 2
If the array has <=three parts, it should give an error i.e move 100 would be invalid and generate an error or if mistyped/mispelt i.e mive 100 this would be invalid and generate an error, and move a would be invalid as "a" is not an integer.





 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:6. command.equals("COLOUR") it seems program is not meant to be created for US market, no worries for that, that was more of a puzzle

Could easily be handled in the switch()
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have update the code, sorry about the format, but I need to run in the menu to draw the line, to check the validation. I understand this is to do with the action listener?

drawing app





 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The break; at line 84 is inside the if() block. If your if() at line 70 is false then the processing will fall through to line 87 which is "LINE:". Move break after line 85 to fix this problem.
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As I look more closely there are a number of issues you have here. What happened to this idea? Let doMove() do the heavy lifting.


 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think that code is in the wrong place. It shou‍ld be in a different class, one not concerned with displays. CB is right that all the work shou‍ld be moved to a separate method. You would then not ask for new input via text components. You would copy the input, validate it, and in the event of incorrect input, throw an Exception. You would have another class which is doing the reading, and that class might catch the exception by asking for new input. There are various other ways to validate input.
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Using my code as an example, how could I validate the information in the j text area to display an error on which line is wrong?

Then how do I make it display the commands to the graphics panel

Please note, that I have only started Java recently and still trying to understand how it works
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Something like this...
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Or... using some helper validation methods...

 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are all sorts of ways you can validate the input. If you got to COLOUR, you would expect three ints in the range 0...255. It all depends what sort of parameters you have in the method; let's see what happens if validateForColour takes a String[] whose first element is "COLOUR".I do not believe there is any risk of args[0] being null, but the form with the literal before the . in line 4 will reliably obviate the risk of a NullPointerException.

[edit]Noticed mistake. Changed i >= 0 to j >= 0 in line 13 of the code block. Also had forgotten to declare j
 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A few minutes ago, I wrote:. . .
args.length == 4 // COLOUR r g b makes 4 elements
. . .
The 4 is part of the expression which continues with && on the next line; the // starts a line end comment. The 4 comes up the same colour as the comment in the code tags.
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Now the next question is once the commands are validated to then draw on my graphics panel

 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, let's see your validation for all the potential inputs. Then see how you are going to pass a corrected version to the method. Or at least make sure you can do all that and keep quiet about the code. You may need extra methods which “drive” execution while you are not using a GUI and not use them when the GUI is working. Once you have got all that working, then you will have the ammo for the drawing

BTW: Somebody else asked a question about a similar subject this morning. Obviously there are several of you doing the same course who have related problems.
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the help

Once I have figured out where to put your code so it works with my code(ANY HINTS),

I was going to adapted your colour code to


 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Seems like the TEXT command may need to be handled differently.
OK, it starts with the command like all the others, but if you do a split before passing it to validateText() you'll be splitting up the text string. Not sure how you want to handle that. Maybe it won't make any difference in validate but it would when you go to execute it. You could punt and assume that there's a single space between all the arguments and paste them back together. It would probably work if your split delimiter was "\\s" but not if it is "\\s+". Using "\\s" causes its own set of issues for the other commands. A robust solution is to let the individual validators each split it the way that works best for them.
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I would have taken a different design approach. Rather than having individual validators I would have called constructors for individual DrawingOperations (e.g. TextOp). Letting the constructor throw an exception if the arguments are invalid. Each DrawingOperation would implement a draw( Graphics2D ) method. The main program would add each Op to a list and when done creating a list of all of the Op's, loop through the list calling draw().

By having individual validators you are requiring that the validator parse the arguments for validation and then when you go to execute it some re-parsing would be necessary (e.g. converting a String to an int).

Because you have a MOVE command, your program will need to keep track of the current position as the commands are executed. A Graphics object won't do this for you. A Line command, for instance, only takes two arguments x,y and will draw a line from the current position to the x,y coordinate. So, a question, does the x,y coordinate become the new current position?
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have adjusted the code, but valid instruction say for move, it is now showing the Invalid Parameters On MOVE error before displaying the instructions.

Can someone see where the logic is wrong?



 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Kirk Preston wrote:. . .
No, don't print an error message in that message. Any error messages are the responsibility of something else. Also make sure to return a boolean from that method, or throw an exception in the case of an error. Don't return Strings.
You appear to have tweaked my method to validate lines. Don't do that. If you are going to use methods for validation (take note of Carey Brown's suggestion of an alternative approach), then you will want to write a new method rather than altering an old method: validForLine or similar.
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Could the new-line be tripping you up?
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Validation on my code works except on one condition

MOVE  give the error in default i.e A valid command has no value or invalid command, instead of Incorrect number of instructions provided on MOVE in the move if else statement



then I need to work out how to draw on the graphics panel (it's going to be another frustrating day)
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Change

To
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Unfortunately, if I change the code to move ==3 then it breaks the validation , as move 100 is accepted as valid.
 
Knute Snortum
Sheriff
Posts: 3734
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

This code implies that the only correct number of arguments for MOVE is anything except three.  Is that really what you want?
 
Kirk Preston
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, if I have a text file with either MOVE , MOVE 100, these should be invalid and generate an error message, if I have a text file with MOVE 100 200 this is valid.

The only file that should be valid is CLEAR as this has no values, i.e CLEAR should reset everything to default, as in a clean canvas.
 
Knute Snortum
Sheriff
Posts: 3734
90
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if I have a text file with either MOVE , MOVE 100, these should be invalid and generate an error message, if I have a text file with MOVE 100 200 this is valid. 

Then line 70 should be ==, not !=.  The same logic error is in all the if statements in the switch block.
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:I think I would have taken a different design approach. Rather than having individual validators I would have called constructors for individual DrawingOperations (e.g. TextOp). Letting the constructor throw an exception if the arguments are invalid. Each DrawingOperation would implement a draw( Graphics2D ) method. The main program would add each Op to a list and when done creating a list of all of the Op's, loop through the list calling draw().
A typical Op would look like this:
We take advantage of throwing an exception when there's a problem with the command line. Notice that there is no try/catch block around parseInt(), we just let any exception it may throw propagate up.

We also provide a polymorphic draw() method to do the actual drawing later.

Your command parser then simplifies to this:
We catch the exception and then throw a new exception with additional information in the message string.

Lastly, the panel class must override the paintComponent() method:




 
Campbell Ritchie
Sheriff
Posts: 54583
151
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:. . . throwing an exception when there's a problem with the command line. Notice that there is no try/catch block around parseInt(), we just let any exception it may throw propagate up. . . .
/what you are doing by that is signalling that you think the current constructor shouldn't handle the Exception or it is beyond the capabilities of the constructor to handle it; any corrections need to be done elsewhere.
 
Carey Brown
Saloon Keeper
Posts: 2645
40
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Carey Brown wrote:. . . throwing an exception when there's a problem with the command line. Notice that there is no try/catch block around parseInt(), we just let any exception it may throw propagate up. . . .
/what you are doing by that is signalling that you think the current constructor shouldn't handle the Exception or it is beyond the capabilities of the constructor to handle it; any corrections need to be done elsewhere.
Exactly. Good explanation.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!