Cannot use IOException in AbstractAction - java

I have run into a curious issue. I need to export some text to a file as a result of pressing a button in a GUI. I cannot, however, apply an IOException to the actionPerformed method of the AbstractAction that is called by the event. I am at a loss as to how to get around this.
Here is the export class:
import java.awt.event.*;
import java.lang.*;
import java.util.*;
import java.io.*;
public class ExportRunner
{
public static void exportToFile(ArrayList<Locker> list) throws IOException
{
}
}
And the AbstractAction extension:
class Export extends AbstractAction
{
public Export()
{
super("Export");
}
public void actionPerformed(ActionEvent e)
{
ExportRunner.exportToFile(list);
}
}

First of all are you sure you want to re throw the exception or maybe is better to handle it and/or show a message to the user?
Option 1: re-throw the exception (ugly in my opinion):
public void actionPerformed(ActionEvent e) {
try{
ExportRunner.exportToFile(list);
} catch(IOException ioex) {
throw new RuntimeException(ioex);
}
}
Option 2: catch and handle it:
public void actionPerformed(ActionEvent e) {
try{
ExportRunner.exportToFile(list);
} catch(IOException ioex) {
handleItOrShowMessageToUser(ioex);
}
}

I would normally pass in a "error handler" to the action class that would allow the delegation of the responsibility of dealing with showing/reporting the error to another part of the application...
Something like...
public interface ErrorListener {
public void errorOccurred(String msg, Exception exp);
}
Then you could pass it to you action...
public class Export extends AbstractAction
{
private ErrorListener errorHandler;
public Export(ErrorListener errorHandler)
{
super("Export");
this.errorHandler = errorHandler;
}
public void actionPerformed(ActionEvent e)
{
try {
ExportRunner.exportToFile(list);
} catch (IOException exp) {
errorHandler.errorOccurred("Failed to export file", exp);
}
}
}
Obviously, somewhere, you need a implementation to handle the callback ;)
You might like to have a look at the Exception trail for more information

Related

My button can't open my class

Basically, the problem is I created an interface with Java Scene Builder. And from FXML button I wanted to open my class.
#FXML
public void pressButton(ActionEvent event) throws Exception {
Platform.runLater(() -> {
try{
new SerialChart().start(new Stage());
} catch (Exception e) {
e.printStackTrace();
}
});
}
#FXML
public void pressButton2(ActionEvent event) throws Exception {
Platform.runLater(() -> {
try {
new Main().start(new Stage());
} catch (Exception e) {
e.printStackTrace();
}
});
}
And my Main can be open, but my SerialChart can't be opened. It says "The constructor SerialChart() is undefined". So here is the problem I think
public SerialChart(String title) {
super(title);
I think this is the problem why I can't open. Please help me... I can show you the whole code if you need.
Like Jim Garrisson said, your constructor that you call takes no arguments, but your defined one does (String title). This means you need to pass in a String argument (Even a blank one like "" will work) when you call it in the Button function.
new SerialChart("Some Title").start(new Stage()); //should be your call in the Button function.
so this is the answer I figured out SO HAPPY
public void pressButton(ActionEvent event) throws Exception {
Platform.runLater(() -> {
try{
SerialChart serialChartDemo = new SerialChart("Clean Energy Data Real time graph");
serialChartDemo.pack();
RefineryUtilities.centerFrameOnScreen(serialChartDemo);
serialChartDemo.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
});
}

SEVERE: Could not dispatch event: Eventbus com.google.common.eventbus.SubscriberExceptionContext

For EventBus, I merged the code inside my java Spring app and have full control of it but the result didn't change.
When I run The EventBus in spring sts (javaw), there is no issue but when I run in the server with java -jar project.jar it gives the same SEVERE: Could not dispatch event: error
The below didn't work for me..
package edu.uams.event;
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.Executor;
import org.apache.log4j.Logger;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventHandler;
import com.google.common.eventbus.SubscriberExceptionHandler;
import edu.uams.domain.TirEvent;
import edu.uams.pacs.IncomingFileMonitor;
public class AysncTraumaEventBus extends AsyncEventBus {
private final static Logger logger = Logger.getLogger(AysncTraumaEventBus.class);
private String name = null;
public AysncTraumaEventBus(Executor executor,
SubscriberExceptionHandler subscriberExceptionHandler) {
super(executor, subscriberExceptionHandler);
logger.info("AysncTraumaEventBus created.");
}
public AysncTraumaEventBus(String name, Executor executor) {
super(name,executor);
this.name=name;
logger.info("AysncTraumaEventBus created. Name:"+this.name);
}
#Override
public void register(Object object) {
super.register(object);
}
#Override
public void unregister(Object object) {
super.unregister(object);
}
#Override
public void dispatch(Object event, EventHandler wrapper) {
try {
logger.info("Let's dispatch Aysnchroneous Trauma Event:"+ ((TirEvent) event).getResultMessage());
wrapper.handleEvent(event);
} catch (InvocationTargetException e) {
// My logger
logger.error("Could not dispatch event: " + event + " to handler " + wrapper+" e:"+e.getMessage());
logger.info("Lets try to disptach again!");
super.post(new ExceptionEvent(event, e));
}
}
public static final class ExceptionEvent {
public final Object event;
public final InvocationTargetException exception;
public ExceptionEvent(final Object event, final InvocationTargetException exception) {
this.event = event;
this.exception = exception;
}
}
}
Somehow the EventHandler can't invoke the target event..
wrapper.handleEvent(event);
When you look the wrapper (EventHandler):
public void handleEvent(Object event) throws InvocationTargetException {
checkNotNull(event);
try {
method.invoke(target, new Object[] { event });
} catch (IllegalArgumentException e) {
throw new Error("Method rejected target/argument: " + event, e);
} catch (IllegalAccessException e) {
throw new Error("Method became inaccessible: " + event, e);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Error) {
throw (Error) e.getCause();
}
throw e;
}
}
You see that method.invoke(target, new Object[] { event }); throws the InvocationTargetException from the Method.class
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass(1);
checkAccess(caller, clazz, obj, modifiers);
}
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
Somehow it can't invoke.. But the most interesting part is that the same jar file along with EventBus can run fine in STS Run (javaw) but when I run java from commandline as java -jar project.jar it can't dispatch the event..
#Subscribe
#AllowConcurrentEvents
public void receivedDicomFile(TirEvent event){
try {
} catch (ClassNotFoundException e) {
logger.error(e.getMessage());
} catch (SQLException e) {
logger.error(e.getMessage());
} catch(Exception e){
logger.error(e.getMessage());
}
}
It always needs an try catch.. Thanks #dwnz for your help

A blocked external process in a swing GUI

I am developing an encoder with java swing and ffmpeg. I created a GUI interface in which I specify my inputs (devices, frame rate, bitrate..). Then I call ffmpeg to encode and stream.
My problem is that the encoding class is well executed from a main class but it is blocked when called from the swing interface (specifically jButtonactionperformed()).
Can anyone help me?
here is my button action
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
Encode s = new Encode();
s.Encode(cmdLine);
}
and here is my encoding method
public void Encode(String cmdLine) {
try {
Process p2 = Runtime.getRuntime().exec(cmdLine);
//logProcessOutputAndErrors(p2);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
Ps: Cmdline is the command i collect from inputs
First, you convert your Encode method into a Runnable class.
public class Encode implements Runnable {
protected String cmdLine;
public Encode(String cmdLine) {
this.cmdLine = cmdLine;
}
#Override
public void run() {
try {
Process p2 = Runtime.getRuntime().exec(cmdLine);
// logProcessOutputAndErrors(p2);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Then, you instantiate the class as a Thread, and start it.
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
Encode s = new Encode(cmdLine);
new Thread(s).start();
}

java.lang.StackOverflowError while using LWJGL's Keyboard class

I have been trying to implement a Keyboard class into my game and received the exception below. This is just a snippet. The full exception goes on for ages longer than this.
Exception in thread "main" java.lang.StackOverflowError
at org.lwjgl.opengl.DisplayMode.<init>(DisplayMode.java:63)
at oregon.client.Oregon.<init>(Oregon.java:10)
at oregon.src.Controller.<init>(Controller.java:9)
at oregon.client.Oregon.<init>(Oregon.java:12)
at oregon.src.Controller.<init>(Controller.java:9)
at oregon.client.Oregon.<init>(Oregon.java:12)
at oregon.src.Controller.<init>(Controller.java:9)
Here's the code for the main class (oregon.client.Oregon):
package oregon.client;
import oregon.src.Controller;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class Oregon {
public DisplayMode normal = new DisplayMode(640, 640);
public Controller controls = new Controller();
public boolean fullscreen = false;
public void start() {
try {
create();
} catch (LWJGLException e) {
stop(e);
}
while (!Display.isCloseRequested()) {
events();
Display.update();
}
Display.destroy();
}
public void events() {
try {
controls.getInput();
} catch (LWJGLException e) {
stop(e);
}
}
public void setFullscreen() {
try {
if (!fullscreen) {
Display.setFullscreen(true);
fullscreen = true;
} else if (fullscreen) {
Display.setDisplayMode(normal);
fullscreen = false;
}
} catch (LWJGLException e) {
stop(e);
}
}
public void create() throws LWJGLException {
if (fullscreen) {
Display.setFullscreen(true);
} else if (!fullscreen) {
Display.setDisplayMode(normal);
}
Display.create();
}
public void stop() {
System.exit(0);
Display.destroy();
}
public void stop(Exception e) {
e.printStackTrace();
System.exit(0);
Display.destroy();
}
public static void main(String args[]) {
Oregon oregon = new Oregon();
oregon.start();
}
}
And here's the code for my keyboard class:-
package oregon.src;
import oregon.client.Oregon;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
public class Controller {
public Oregon oregon = new Oregon();
public void getInput() throws LWJGLException {
while (Keyboard.next()) {
if (Keyboard.getEventKeyState()) {
if (Keyboard.getEventKey() == Keyboard.KEY_F11) {
oregon.setFullscreen();
}
}
}
}
}
If there is an expert out the with LWJGL, could you please help me out? Thank you and I hope I do get some help. :D
Nothing to do with LWJGL. Stack overflows in simple code are always because of accidental infinite loops. You have one: Controller tries to create an Oregon (this line: public Oregon oregon = new Oregon();), which then tries to create a Controller, which tries to... (etc..)
When you create an Oregon instance, it creates a Controller instance, which creates an Oregon instance, which creates a Controller instance, which creates an...
What you should probably be doing is not creating an Oregon instance in your controller, but passing your existing instance as a parameter to the Controller constructor and storing that (or the other way around).
Pseudo code:
public Oregon() {
controller = new Controller(this);
...
}
public Controller(Oregon oregon) {
this.oregon = oregon;
...
}

Java: Throw an exception to another Thread

I have a java code like this:
private class Uploader implements Runnable
{
// ...
public void start()
{
t.start();
}
public void run()
{
try {
while(i=in.read())
{
output.write(i); // THIS IS A BLOCKING CALL !!
}
} catch(ProtocolException e) { ... }
catch(IOException e1) { ... }
}
private void restore()
{
...
}
private class Checker implements Runnable
{
// ...
#Override
public void run()
{
// I WANT (IN A PARTICULAR MOMENT) TO THROW AN
// EXCEPTION INTO THE Uploader RUN METHOD FROM HERE,
// IS IT POSSIBLE?
}
}
}
The problem is that i have a blocking write() in the Run() method, so I have added a
new thread that checks whether or not the connection is transmitting: if it's not trasmitting I want to stop the blocking write() using the exception mechanism (throwing an exception to the other thread's run() method from the checker thread).
Is it possible?
EDIT [SOLVED]:
The only way is to brutally close the output stream and to work on the amount of written bits to check whether the connection is transmitting:
private class Uploader implements Runnable
{
private OutputStream output;
private int readedBits;
public void run()
{
try {
while(i=in.read())
{
output.write(i);
readedBits++;
}
} catch(IOException e1)
{
// ENTERS HERE IF RESTORE() IS CALLED
}
}
private void restore()
{
try {
output.close();
} catch (IOException e) {}
// Restore connection ....
}
private int getReadedBits()
{
return this.readedBits;
}
private class Checker implements Runnable
{
// ...
#Override
public void run()
{
while(true)
{
try {
Thread.sleep(timeout);
} catch (InterruptedException e1) {}
if(lastReaded >= getReadedBits())
restore();
else
lastReaded = getReadedBits();
}
}
}
}
You can make your code honor Thread.interrupt() call. See javadoc of this call.
Not exactly what you've asked for but I'd rather use java.nio and
public abstract int select(long timeout) throws IOException
to (not only) detect timeouts.
In general with blocking on I/O the only way to move on is to close the resource. As #VolkerK says, the other approach is to use non-blocking I/O, which is more difficult.
I recommend using Interrupts for this. Checker may call interrupt on Uploader class.
E.g.
private class Checker implements Runnable
{
// ...
Uploader uploader;
public Checker(Uploader uploader) {
this.uploader = uploader;
}
#Override
public void run()
{
// CHECK
if(failed) uploader.interrupt();
}
}
Documentation is here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Categories

Resources