Action listener/Throws IOException Conflict - java

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)

Related

Using one button to pull information from several panels

I'm building this form that I want to be able to change what fields are displayed based on what setting you select.
There's going to be 3 panels, first with text fields gathering information, second for notes, third for a checklist. The main frame will add those panels onto it and use one buttons to gather the information from each panel and compile it into a text area so you can just copy/paste it after it's been formatted.
So the problem I'm having is getting the information passed over to the main frame. I have created a formlistener to pass information from the form using an object FormEvent I have created which will carry over the necessary information. I have then created a method in the form to pull the relevant information depending on which form is being used at the time. My problem is getting that method to call properly. This is the ActionListener for the button:
confirm.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
form.getUbntInfo(); // this is where i have it set
form.setFormListener(new FormListener() {
// would like it to go here so that it creates the event
// object to pass before
// it passes the information, but it causes compile error here
public void formEventOccured(FormEvent e) {
String complaint = e.getComplaint();
String ping = e.getPing();
String ap = e.getAp();
signal0 = e.getSignal0();
signal1 = e.getSignal1();
chain0 = e.getChain0();
chain1 = e.getChain1();
sinr0 = e.getSinr0();
sinr1 = e.getSinr1();
sinr0 = e.getLan();
System.out.println("local signal: " + signal0);
}
});
Essentially the getUbntInfo(); method needs to have a formListener set so that it can pass create the object to pass along the information. As it stands I can press the button twice and it passes the information the second time but it will not do it the first time. What am I doing wrong?

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.

how to autogenerate code in 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");
}
});

Can't call method from another class

I have two classes.
The main one opens the second one in a jframe in which the user will press a button and trigger a method from the main class/jframe editare(String value) that will automatically add some data to some jtextfields in the main jframe.The problem is that it won't trigger the method.I tried calling other methods from the main class,it doesn't call them either.I tried a lot of stuff for like the past 1-2 hours,can't figure it out.
Here is some code :
From the second jframe :
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
Test2 test2=new Test2();
test2.citireser(list.getSelectedValue().toString()); //won't work.works if i call it from the same method,the main one
test2.restart(); //won't work either
this.dispose(); }
From the first jframe,the main one :
public void citireser(String cur) {
try {
serializedPath = "C:/Inter/" + cur;
InputStream file = new FileInputStream(serializedPath);
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream(buffer);
String[] storeAllArraysREAD[] = (String[][]) input.readObject();
prodr = storeAllArraysREAD[0];
cantr = storeAllArraysREAD[1];
pretr = storeAllArraysREAD[2];
input.close();
buffer.close();
file.close();
System.err.println("prodr[1]= "+prodr[1].toString());
for (int m = 0; m < prodr.length - 1; m++) {
allprod.get(m).setText(prodr[m]);
allcant.get(m).setText(cantr[m]);
allpret.get(m).setText(pretr[m]);
produsnou();
}
} catch (ClassNotFoundException ex) {
System.err.println("EROARE");
} catch (IOException ex) {
System.err.println("EROARE");
}
}
EDIT : Ok,after trying different stuff for a couple of hours i've got it.
public class Opt extends javax.swing.JFrame implements Printable {
private final Test2 main;
public Opt(Test2 aMain) {
main = aMain;
try {
} catch (Exception e) {
e.printStackTrace();
}
initComponents();
jScrollPane2.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
jScrollPane2.getVerticalScrollBar().setUnitIncrement(16);
citirel();
if (list.getModel().getSize() == 0) {
jButton1.setEnabled(false);
jButton2.setEnabled(false);
}
}
Thanks for your help,i don't know who i should pick as the right answer :( Sorry to the other guy
The problem here is that you're working with a new instance of Test2. In the action performed (first block of code), you're creating a new Test2 (which would be the first frame). You have to keep somewhere (usually a field) the reference to the first Test2 created.
If you're having further issues, consider editing your question and posting the full code (the two frames entirely, at least). My spider senses are telling me that there's some context missing.
Also, we have similar family names. :-)
Please correct me if any of this is wrong, as I'm trying to understand your program from incomplete code:
Test2 (a JFrame containing your program entry point main(string[])) at some point creates a second class (also a JFrame) and opens it.
When you click a certain button in your second window, you wish to modify some elements of the Test2 window, and close the secondary window.
Assuming the above is correct, there is one obvious problem I can see in the code snippets you've posted.
In jButton3ActionPerformed, you're creating a new Test2 object, and modifying that. If you want to modify the original window, you need to be storing a reference to it. For example, require a Test2 object as a parameter to your second class, and store that parameter as a field in the class.

Custom Console nullPointerException when checking for existing text

i have created a custom console for a program. I have a method that adds a message to the console called toConsole this asks for the string where it checks and adds the time to the string. it then goes to my function addConsole which checks if existing text is present if so it will then add the pre-existing text to the new text, else it just puts the new text in. so here is the error. i may also point out that if i enter text manually on the consoles input text box it does not produce this error.
Exception in thread "main" java.lang.NullPointerException
at com.michael.tech.api.console.RunConsole.addConsole(RunConsole.java:188)
at com.michael.tech.api.console.RunConsole.toConsole(RunConsole.java:204)
at com.michael.tech.api.console.RunConsole.toConsole(RunConsole.java:223)
at com.michael.tech.api.testerFile.main(testerFile.java:25)
here is the addConsole method
private static void addConsole(String s){
console.setText( ( console.getText().isEmpty()) ? s : (console.getText() + "\n" + s) );
}
the toConsole method
public static void toConsole(String s, boolean timeStamp, boolean classPath, String className){
if(s.startsWith("/")){
doCommand(s);
return;
}
Time t = new Time();
t.getSYSPrint();
String time = "[" + t.toMilitary() + "] ";
if(EchoTime || timeStamp){
addConsole(time + s);
}
else if(classPath){
addConsole(className);
}
else{
addConsole(s);
}
}
and lastly the Main method in testerFile class
public static void main(String[] args) {
RunConsole.startConsole();
RunConsole.toConsole("test");
}
Thanks in advance for any help. I assume it is some small mistake i overlooked (I hope too).
EDIT:
paste bin to see line numbers
RunConsole class
http://pastebin.com/2yUAwQc5
testerFile class
http://pastebin.com/R5ViLekp
The problem is that the JTextArea console still has its default null value as it has not been instantiated. This is because there is no instance of RunConsole created — Instead, you are accessing the methods of this class in a static way:
RunConsole.startConsole();
RunConsole.toConsole("test");
Using static methods is poor design especially since your application needs to have state. Make all static methods in RunConsole instance methods and replace the above lines with:
RunConsole runConsole = new RunConsole();
runConsole.startConsole();
runConsole.toConsole("test");
Also, when you do this, don't forget to remove your instance created in startConsole, otherwise you will not see the initial message from toConsole. Change:
new RunConsole().setVisible(true);
to
setVisible(true);

Categories

Resources