how to autogenerate code in java? - java

I am making a GUI where a person clicks on a checkbox and a code for whatever he checked on is generated and appended to the java file.
For example, a check box saying "Output to the console function" will generate...(I can handle the GUI, don't worry about that ^_^)
public static void log(String text){
System.out.println(text);
}
I can hard code that but I know how to hard code that in a form of a string and I can then print that to the console. I don't know how to append it to the file itself. I can append it to a text file if thats useful.
I love the auto-generated try-catch block. It is sort what I am expecting. You click on surround with try-catch block. Currently, my code can just output whatever I want in a form of a string.
EDIT:
To make it simpler, new scenario :I already have pre-defined functions
names of functions a ,b ,c,d
so there will be 4 checkbox, and all the functions that i checked will be in a new function which i can name via a text box
for example,
If I only checked a AND b
public static void e (){
a();
b();
}

Hopefully this helps!
To append a file,
Use:
File java_file= new File("java_file.class")
PrintWriter out = new PrintWriter(new FileWriter(java_file, true));
Then use an item listener for the checkboxes:
addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
System.out.println(e.getStateChange() == ItemEvent.SELECTED
? "SELECTED" : "DESELECTED");
}
});

Related

How can you turn a String representation of a class into a bona fide Object?

I'm writing a program that needs to have Command Objects. A Command contains a String for its name, and an AbstractAction that represents what the Command actually does. Furthermore, a Command has a method, init(), used higher up in the program's hierarchy that instantiates variables for the Command's use (to provide access to the GUI, network, and so on), and a method, execute(), that executes the AbstractAction on a special Thread. Here is an example of creating and using a Command:
Command c = new Command("Test",
new AbstractAction() {
public void actionPerformed(ActionEvent a) {
System.out.println("Hello world!");
}
});
At this point, calling "c.execute();" will print out "Hello world!", as expected.
My goal is to have a text file with pairs of values, which can be parsed to generate a String name and an AbstractAction action. Once that has been done, another class will go through the found names and actions, create Command Objects for each one, and add them to the list of commands in the program, where they can then be used as normal.
Right now, my problem is that I read in a String that represents the body of the private AbstractAction above- but there isn't an easy way to actually convert the String into an actual AbstractAction Object.
One potential idea was creating a temporary java file with the AbstractAction String representation, compiling it, creating a new AbstractAction from it, and then get that reference using reflection, but that seems like overkill. Another was to directly modify the source of the file that parses through the file, so that it would have the code of the AbstractAction written out, but again, this is a bit crazy.
I've tried a few other implementations, including forcing the user to create a subclass of Command, putting their source into a special program folder, and then creating the Commands on initialisation, but this ended up being a lot of work for the user (lots of redundant code).
Please let me know if there's a better way to implement what I want to do- or if there's an easier way to turn the String of the source into an inner Object as above.
Edit 1:
Here is an example of what the text file would look like:
//Anything outside of quotes is a comment
"Foo", "System.out.println("Hello world!");"
"Bar", "network.sendOverAFile(new File("test.txt"));"
From here, the parser (on startup) would read through the file and extract "Foo" as a String name, and "System ... ;" as a String action. I need to turn action into the code in the body of the AbstractAction, as seen above when creating the Command.
The same would be done for Bar; Bar uses one of the variables passed by init().
As for the subclass implementation I tried, the user would have to create their own subclass of Command, and put it into a source folder. A subclass would look something like this:
public class TestCommand extends Command {
public TestCommand() {
super("Test", new AbstractAction() {
public void actionPerformed(ActionEvent a) {
System.out.println("Hello!");
}
});
}
}
This would then be put into a source directory, among every other subclassed Command, and compiled. The parser would go through the compiled code segments, and add the relevant information to an array. Every time a Command would normally be executed, the parser scans through the list of all names, and if there is a match, execute the relevant AbstractAction. This works, but involves a ton of references to external classes (which will probably slow down the program with dozens of commands), and is two or three times as much work for the users making the plugin. As a result, I felt it would be much easier to use the text file technique above, but I don't know how to turn a String representation of the code into the code itself; Ergo my initial question.
This sounds like a case of overengineering. Do you really need this much flexibility at runtime, or do you simply have a lot of commands and you want an easy way to refer to them in a file?
If it's the latter, your text file doesn't need to contain the code; it just needs to contain symbolic identifiers corresponding to that code. Those identifiers should exist in your code as enum constants:
public enum Command { FOO, BAR }
You should create all of your actions in code, and place those actions in a Map using the enum constants as keys. Your file can then refer to the actions by those enum constants:
public List<Action> parseActions(Path file)
throws IOException {
List<Action> actions = new ArrayList<>();
try (BufferedReader reader =
Files.newBufferedReader(file, Charset.defaultCharset())) {
String line;
while ((line = reader.readLine()) != null) {
Command command = Command.valueOf(line);
Action action = getAction(command);
actions.add(action);
}
}
return actions;
}
private Map<Command, Action> allActions;
private Action getAction(Command command) {
Objects.requireNonNull(command, "Command cannot be null");
if (allActions == null) {
allActions = new EnumMap<>(Command.class);
allActions.put(Command.FOO, new AbstractAction() {
public void actionPerformed(ActionEvent event) {
System.out.println("Hello world!");
}
};
allActions.put(Command.BAR, new AbstractAction() {
public void actionPerformed(ActionEvent event) {
network.sendOverAFile(new File("test.txt"));
}
};
// Safety check
if (!allActions.keySet().containsAll(
EnumSet.allOf(Command.class))) {
throw new RuntimeException(
"Not every Command constant has an associated Action");
}
}
return allActions.get(command);
}
To conform to the above, your text file would simply contain:
FOO
BAR
If you really and truly need fully dynamic code that can be read from a text file, bear in mind that it is a tremendous security hole. In fact, it is the very definition of code injection: anyone can place arbitrary code (including things like Runtime.getRuntime().exec("rd /s/q C:\\Windows\\System32") or Runtime.getRuntime().exec("rm -rf ~")) in a file and your program will gladly run it.
If you're still sure that you want to do it, you'd probably want to use the JavaScript engine that comes with every Java runtime:
public List<Action> parseActions(Path file)
throws IOException {
List<Action> actions = new ArrayList<>();
final ScriptEngine engine =
new ScriptEngineManager().getEngineByName("JavaScript");
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("network", myNetwork);
try (BufferedReader reader =
Files.newBufferedReader(file, Charset.defaultCharset())) {
String line;
while ((line = reader.readLine()) != null) {
String[] nameAndCode = line.split("\\s+", 2);
String name = nameAndCode[0];
final String code = nameAndCode[1];
Action action = new AbstractAction() {
public void actionPerformed(ActionEvent event) {
engine.eval(code);
}
};
actions.add(action);
}
}
return actions;
}
Each line in your file would contain a command name followed by JavaScript code. So it might look like this:
Foo importClass(java.lang.System); System.out.println('Hello world!');
Bar importClass(java.io.File); network.sendOverAFile(new File('test.txt'));
Another major disadvantage of doing this, in my opinion, is that the code won't benefit from compiler checks, and you certainly can't set breakpoints in that code from a debugger. All in all, it will be a considerable headache to debug and maintain.

Writing file when closing window

I'm writing a Restaurant Program.
When the user confirms his order, the order gets stored in an array of type order. Why? because when the user chooses to close the program, all orders get saved in a file with item's names and information about each item.
Also, every order object has an array of type item inside it!
Could you help me on how to write that file?
I know it'll be in the method processWindowEvent.
This is my try, i know that i should remove textArea.getText() but i don't know how to print all items, neither.
protected void processWindowEvent(WindowEvent e){
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
JOptionPane.showMessageDialog(this,"All operation have been saved ");
try{
outFile=new File("Orderslist.txt");
out=new FileOutputStream(outFile);
ob=new PrintWriter(out);}
catch(IOException M){M.getMessage(); }
for(int i=0;i<o2.length;i++){
if(o2[i]!=null){
if(o2[i].getCount()<=4)
ob.println(o2[i].toString()+"\n--------------\n"+textArea.getText()+"--------------\n"+"\nTotal: "+o2[i].getTotalPrice());
else if(o2[i].getCount()>4)
ob.println(o2[i].toString()+"\n--------------\n"+textArea.getText()+"--------------\n"+"\nTotal Price#: "+o2[i].getTotalPrice()+"\n\nDiscount 20%\n\n--------------\nTotal price#: "+(o2[i].getTotalPrice()-(o2[i].getTotalPrice()*0.2)));
}
}
In the constructor of your Widnow add this:
public Window() {
this.addWindowListener(new WindowAdapter(){
#Override
public void windowClosing(WindowEvent arg0) {
writeFile(textArea.getText()); //Call your method
System.exit(0);
}
});
...
}
For writing the file:
File file = new File("myFile.txt");
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write("Texto to write");
bw.close();
After ob.println() do ob.close(); or ob.flush();.
If you dont close the stream or flush the stream , nothing will be printed in your file.
Really this isn't the best design, you should write changes to the file immediately as they are made. The reason for this is that if the application closes for any other reason (power cut, task manager kill, crash, etc) then you don't want to lose the user's data. It would also be worth automatically backing up that file (for example copying it after startup) so if you corrupt the current session somehow you can revert.
To actually implement the saving you want to use a FileOutputStream of some sort but the exact implementation will vary a lot depending on the format that you want the data inside the stream. For example XML, JSON, plan text, binary serialization etc are all fairly easy but you need to pick one :)

Action listener/Throws IOException Conflict

I am attempting to make a GUI for a program that reads and writes information from a random access file and display it at will. I cannot manipulate anything but the GUI and must refer to prebuilt methods( if the methods truly are unusable then I can make an exception).
The Part I am having issues with is dealing with an IOException while writing to a file.
public static class EdtButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("Confirm")) //if the confirm button is pressed
{
writeAll(); //runs all write methods using the strings from the text field
frameAddMovie.setVisible(false);
}
The writeAll refers to a series of methods that write from a file based on the string it is passed, these strings come from textfields on my GUI Window. They all look something like this;
public static void writeDirector(int recordNum, String directorIn)throws IOException
{
int position;
RandomAccessFile recordFile = new RandomAccessFile("RecordFile", "rw");
position = recSize * (recordNum-1)+32; // read 32 spaces into the record to the start of the director line
recordFile.seek(position);
recordFile.writeBytes(directorIn);
}
At the point were the Confirm button is pressed and writeAll() is run there is an IOException thrown that cannot be caught with the method or the Class.
if (e.getActionCommand().equals("Confirm")) //if the confirm button is pressed
wouldn't you want that to be
if (e.getSource() = buttonname)

set focus for all fields

I noticed I can use getName() as part of the trick.
What is java.awt.Component.getName() and setName() used for?
But I don't really have a clue where to start. What type of listener should I use (assuming the textfield / or box is currently blinking / selected)
This is my previous question, and thank you for the help guys.
How do I use requestFocus in a Java JFrame GUI?
I realize that for each component (Textfield) that I am creating, I have to insert a statement like requestFocus (or using transferFocus).
Is it possible to apply this policy to all the fields???
I have several textfields and ComboBox. The problem I hit is that I don't want to write methods for every single field / box.
For example, I write a method like this
private JTextField getFirstNameEntry() {
.... do something
}
because my instructor writes his program like this
private JPanel getJContentPane() {
jContentPane = new JPanel();
jContentPane.setLayout(new java.awt.FlowLayout(FlowLayout.LEADING));
jContentPane.add(makeLabel(" First Name *", 100, 20));
jContentPane.add(getFirstNameEntry(), null);
jContentPane.add(makeLabel(" Middle Initial", 100, 20));
jContentPane.add(getMiddleInitialEntry(), null);
// etc
return jContentPane;
However, to save redundancy (that was my motive at first), say I have a box, I can simply add the following code inside the method above: getJContentPane()
titleBox = new JComboBox(new String[]{"Mr.","Mrs.","Ms.","Dr.","Prof.","Rev."});
jContentPane.add(titleBox);
But doing this, I still need to create a method to do addItemListener
private void setComboBoxFocus() {
titleBox.addItemListener(
new ItemListener(){
public void itemStateChanged(ItemEvent e){
if(e.getStateChange() == ItemEvent.SELECTED)
{
String titleSelected = titleBox.getSelectedItem().toString();
System.out.println(titleSelected);
titleBox.transferFocus();
}
}
});
}
However, this doesn't really save redundancy at all. If I have more than one ComboBox to be added, I would have to write another similar method. In fact, even in the case with one ComboBox (titleBox), I would still end up with writing a method for titleBox.
So my question is: is there a way to write a general method that can call focus to all (maybe one for ComboBox type)?
Thank you and sorry for the long post.
Why not take a JComboBox argument to your setComboBoxFocus() method, which allows you to set that listener to any JComboBox you may have? Like so:
private void setComboBoxFocus(JComboBox box) {
box.addItemListener(
new ItemListener(){
public void itemStateChanged(ItemEvent e){
if(e.getStateChange() == ItemEvent.SELECTED)
{
String titleSelected = box.getSelectedItem().toString();
System.out.println(titleSelected);
box.transferFocus();
}
}
});
}

Simplest way of creating java next/previous buttons

I know that when creating buttons, like next and previous, that the code can be somewhat long to get those buttons to function.
My professor gave us this example to create the next button:
private void jbtnNext_Click() {
JOptionPane.showMessageDialog(null, "Next" ,"Button Pressed",
JOptionPane.INFORMATION_MESSAGE);
try {
if (rset.next()) {
fillTextFields(false);
}else{
//Display result in a dialog box
JOptionPane.showMessageDialog(null, "Not found");
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
Though, I do not really understand how that short and simple if statement is what makes the next button function. I see that the fillTextFields(false) uses a boolean value and that you need to initialize that boolean value in the beginning of the code I believe. I had put private fillTextFields boolean = false; but this does not seem to be right...
I'm just hoping someone could explain it better. Thanks :)
Well, fillTextFields(true); is a function call and when you pass in a true/false flag it does some things (you have to see the code inside the function in order to find out exactly what it does).
The field declaration private fillTextFields boolean = false; is invalid, you're supposed to provide the type before the name, e.g.: private boolean fillTextFields = false;. Aside from the invalid syntax that flag really doesn't do anything, especially if you're not using it anywhere.
I don't understand what else you expect to see in the jbtnNext_Click() method... when you declare your button and it gets clicked on the UI, then this method gets invoked. It doesn't make the button work, the button works even when you have nothing in the jbtnNext_Click() method. For example:
private void jbtnNext_Click() {
// The button will still work, but it simply won't do anything
}
Getting a button to function depends on what you view as a functioning button. What is supposed to happen when you click next/previous?
Update:
I thought that I needed the boolean
declaration to make the
"fillTextFields(false)" work.
Was the fillTextFields method given to you somewhere? If it was, then you don't need to declare anything, much less a variable. If it's already provided, then you just call the method, that's all. If it's not provided then you need to declare it:
private void fillTextFields(bool shouldFill)
{
if(shouldFill)
{
// fill the text fields
}
// possibly have an else statement if you need to do something else here
}
Otherwise what you see in that function is all you need to do in order to go to the next record in the database.
I think that the code provided is a bit short to provide a good explanation, posting the code for fillTextFields would be of more help.
What I can guess that the program is doing is that it is retrieving some data from a database. The next button allows the program to iterate through the items that have been returned.
Once that the next button is pressed, a message box is shown to let you "know" that the button has indeed been pressed.
rset.next returns true of there is another element in the list (retrieved from the database), or false if there isn't.
If it returns true, you are calling the fillTextFields methods, which I guess displays the data on screen (even though without the code I can just speculate). If there isn't anything left, a message box displaying "Not Found" is shown.
With regards to your question about
private fillTextFields boolean = false;
fillTextFields is a method, and you cannot assign values to methods. Also, in Java, when declaring both methods and variables, the type is written before the name, such as
private int number;
public float myMethod() { }
The next button won't do anything unless you register an action with the button. What I mean is, wherever your next button is defined looks something like this:
private JButton nextButton = new JButton("Next");
This creates a button that has the label, 'Next'. There might be some additional code for positioning the button. In order for that button to do anything when it is clicked, it needs to have an Action set on it, or it has to have an ActionListener added to it. Many times, the class that is creating the button implements ActionListener and has a method to respond to the click, something like:
nextButton.addActionListener(this);
...
...
...
public void actionPerformed(ActionEvent e) {
// some method implementation
}
The actionPerformed method is called when the button is clicked, AS LONG AS you've registered the action listener on the button. Is anything like this present in the code from your professor?

Categories

Resources