how can add busy cursor to every event in application - java

I am doing desktop application using swing and want busy cursor to every event
current using code
try {
Cursor hourglassCursor =
Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR); this.setCursor(hourglassCursor);
doProcessing();
}
finally {
Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
this.setCursor(normalCursor);
}
I want apply global function that apply on every event
Please help me

You can create a method that sets Cursor to the Component
public void doProcessing(Component component, Runnable process){
if (component==null || process==null){
return;
}
component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
try {
SwingUtilities.invokeAndWait(process);
} catch (InterruptedException | InvocationTargetException e) {
e.printStackTrace();
}
component.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}

Related

PixelCopy android implementation

I am new to android development so I think this may be a teething issue on my part, but I am currently trying to use the PixelCopy function in android studio. I have code as shown below, and it matches what the base class is expecting although it is returning an error. Would anyone be able to assist me with this issue?
The code I currently have is as follows:
final HandlerThread handlerThread = new HandlerThread("PixelCopier");
handlerThread.start();
SurfaceView current = new SurfaceView(view.getContext());
PixelCopy.OnPixelCopyFinishedListener copyResult;
// Make the request to copy.
PixelCopy.request(current, bitmap, copyResult, handlerThread);
if (copyResult. == PixelCopy.SUCCESS) {
//If successful do tasks in here
}
Try crating extracting finish listener as shown below in class.
private static void onPixelCopyFinished(int result) {
if (result != PixelCopy.SUCCESS) {
Log.e("err", "errMsg");
return;
}
}
You can pass the listener as below and also you'll also need to wrap it in try catch as it might throw an exception.
try {
PixelCopy.request(current, bitmap, <YOUR CLASS>::onPixelCopyFinished, this.getHandler());
} catch (IllegalArgumentException e) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace();
}

Getting 'invalid drawable'

I'm trying to use OpenGL directly from Java using JNA on Mac OSX (I have done it successfully with Windows and Linux). I've browsed thru JOGL source but they use CALayers which I don't understand yet. I would like to just simply use NSOpenGLView if possible and place it over top the AWT Canvas. I find the NSWindow using JNA and add the NSOpenGLView I created and it seems to work except when I call [nsOpenGLContext setView] or [nsOpenGLView lockFocus] I get an 'invalid drawable' error. I learned from Rococoa how to use ObjectiveC from Java.
Here is some sample code:
private static boolean createMac(GL gl, Component c) {
NSAutoreleasePool pool = new NSAutoreleasePool();
pool.alloc();
pool.init();
gl.nsopenglview = new NSOpenGLView();
gl.nsopenglview.alloc();
Pointer ptr = Native.getWindowPointer(findWindow(c));
NSObject nsComponent = new NSObject();
nsComponent.obj = ptr;
Pointer cClass = nsComponent._class();
NSView view = new NSView();
view.alloc();
boolean isView = view.isKindOfClass(cClass);
// JFLog.log("test=" + isView);
if (isView) {
view.dealloc();
view.obj = ptr; //do NOT dealloc this (usually NSWindowViewAWT)
gl.nswindow = view.window();
} else {
view.dealloc();
gl.nswindow = new NSWindow();
gl.nswindow.obj = ptr;
}
NSOpenGLPixelFormat fmt = new NSOpenGLPixelFormat();
fmt.alloc();
fmt.initWithAttributes(new int[] {
NSOpenGLPFAWindow,
// NSOpenGLPFAAccelerated, //is not available on my test system
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize,24,
NSOpenGLPFADepthSize,16,
0 //zero terminate list
}
);
if (fmt.obj == null) {
JFLog.log("NSOpenGLPixelFormat initWithAttributes failed");
return false;
}
if (gl.nsopenglview != null) {
gl.nsopenglview.initWithFrame(new NSRect(c.getBounds()), fmt);
}
NSView content = gl.nswindow.contentView();
JFLog.log("content view=" + content.obj);
content.addSubview(gl.nsopenglview);
JFLog.log("layered=" + content.wantsLayer());
//use created context
gl.nsopenglcontext = gl.nsopenglview.openGLContext();
//create some resize/move listeners
final GL _gl = gl;
final Component _c = c;
c.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
_gl.nsopenglview.setFrame(new NSRect(_c.getBounds()));
}
public void componentMoved(ComponentEvent e) {
_gl.nsopenglview.setFrame(new NSRect(_c.getBounds()));
}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
});
if (api == null) {
api = new GLFuncs();
gl.glLibrary = NativeLibrary.getInstance("OpenGL");
try {
Field fields[] = api.getClass().getFields();
for(int a=0;a<fields.length;a++) {
String name = fields[a].getName();
try {
fields[a].set(api, gl.glLibrary.getFunction(name));
} catch (Throwable t) {
JFLog.log("OpenGL:Warning:Function not found:" + name);
}
}
} catch (Exception e) {
JFLog.log(e);
}
}
pool.release();
return true;
}
I can't use the drawRect function in NSOpenGLView so I just lockFocus, use gl commands and unlockFocus when done. But the NSOpenGLContext doesn't have a view assigned and trying to assign the one I created generates the 'invalid drawable'.
Any ideas?
If you want a full working demo goto http://javaforce.sf.net and download v7.15.0, run ant in /jf and then in /projects/jtest3d and then execute run.sh (click the GLCanvas test).
I got it working! The problem was in Rococoa (or possibly a bug in JNA). Their NSRect structure does not pass to [NSOpenGLView initWithFrame] or [NSWindow initWithContentRect] properly. If I pass the 4 fields directly (x,y,width,height) to the function instead of the Structure itself then it works. Also I used [NSObject performSelectorOnMainThread] to make sure I do all GUI stuff on the main thread.
So it is possible to use OpenGL using pure JNA from Java. No native code needed.
This should be available in my javaforce.sf.net in v7.16 which I'll release in a while.
Thanks.

Java sockets - weird response

I'm doing a simple server/client communication for my tic tac toe game. All it goes through actionPerformed where I first setIcon to the pressed button, then proceed my performTurn method (there is some win checking), then send the coordinates of the pressed button to the client and then i wait for the other player to send me data about his turn. all it goes well, but......... the first method that should be made (setIcon) is actually done after receiving data from the other player. it goes like this: Game.performTurn, Server.send, Server.receive, setIcon. do anyone know what java issue is it, that the setIcon method doesnt go first? thx lot
public void actionPerformed(ActionEvent e) {
if (clickable && Game.getTurn()) {
clickable = false;
if (Board.player) {
setIcon(X);
Game.performTurn(x, y, Value.FIRST);
try {
Server.send(new ObjToSend(x, y));
} catch (IOException ex) {
Logger.getLogger(XOButton.class.getName()).log(Level.SEVERE, null, ex);
}
try {
ObjToSend bla = Server.recieve();
Board.buttons[bla.getX()][bla.getY()].setIcon(O);
Game.performTurn(bla.getX(), bla.getY(), Value.SECOND);
Game.turn = true;
} catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(XOButton.class.getName()).log(Level.SEVERE, null, ex);
}

JSVGCavas BridgeUserAgent displayError() override

I've met a problem and I've been struggling last 2 days. I have a compiled program that runs some simulations and visualizes the results in an SVG file. The file is replaced every 2 seconds with a new one, until the simulation is done.
Wanting to visualize the results, I made a java swing program which uses batik and JSVGCanvas to display the svg file and update it every 2 seconds.
The code I use is:
// In the main part of my code
svgCanvas = new JSVGCanvas();
oneLineInnerPanel.add("Center", svgCanvas);
(new Thread() {
#Override
public void run() {
try {
Thread.sleep(2000);
File f = new File("file_that_shows_simulation_still_running");
while (f.exists()) {
svgReloadButtonActionPerformed(null);
Thread.sleep(2000);
}
} catch (InterruptedException ex) {
Logger.getLogger(testUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
// -----------------------------------------------
private void svgReloadButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
svgCanvas.loadSVGDocument(SVGFile.toURL().toString());
} catch (MalformedURLException ex) {
Logger.getLogger(testUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
It works fine with the exception that every 30-40 updates, it happens that the loadSVGDocument tries to read the document while it's being written by the simulator and thus I get a jdialog error:
XML document structures must start and end within the same entity.
org.apache.batik.dom.util.SAXIOException: XML document structures must start and end within the same entity.
at org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:437)
at org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:349)
at org.apache.batik.dom.svg.SAXSVGDocumentFactory.createDocument(SAXSVGDocumentFactory.java:200)
at org.apache.batik.dom.svg.SAXSVGDocumentFactory.createSVGDocument(SAXSVGDocumentFactory.java:124)
at org.apache.batik.bridge.DocumentLoader.loadDocument(DocumentLoader.java:106)
at org.apache.batik.swing.svg.SVGDocumentLoader.run(SVGDocumentLoader.java:84)
Caused by: org.xml.sax.SAXParseException; systemId: file:/tmp/tempDir9189341730639722289/svgOut.svg; lineNumber: 272; columnNumber: 2; XML document structures must start and end within the same entity.
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.batik.dom.util.SAXDocumentFactory.createDocument(SAXDocumentFactory.java:431)
... 5 more
This doesn't affect the whole procedure, but it's ugly. I get 2-3 of these jdialogs throughout the simulation. I cannot lock the file I/O, because I don't have access to the simulator code. If I lock from java only, the simulator crashes saying it cannot access the file.
What I want is that if there is an error while loading the svg file to somehow catch it internally and not have a jdialog. I can accept missing an update every 30-40 times (60-80 secs).
Now, JSVGCanvas gives you the option to provide a useragent and overwrite the displayError() method to do as you like. I tried that but the dialogs still occur. The problem is that the dialogs are not produced by the svgUserAgent I provide but by an internal BridgeUserAgent:
public JSVGComponent(SVGUserAgent ua, boolean eventsEnabled,
boolean selectableText) {
super(eventsEnabled, selectableText);
svgUserAgent = ua;
userAgent = new BridgeUserAgentWrapper(createUserAgent());
addSVGDocumentLoaderListener((SVGListener)listener);
addGVTTreeBuilderListener((SVGListener)listener);
addSVGLoadEventDispatcherListener((SVGListener)listener);
if (updateOverlay != null)
getOverlays().add(updateOverlay);
}
public void loadSVGDocument(String url) {
String oldURI = null;
if (svgDocument != null) {
oldURI = svgDocument.getURL();
}
final ParsedURL newURI = new ParsedURL(oldURI, url);
stopThenRun(new Runnable() {
public void run() {
String url = newURI.toString();
fragmentIdentifier = newURI.getRef();
loader = new DocumentLoader(userAgent);
nextDocumentLoader = new SVGDocumentLoader(url, loader);
nextDocumentLoader.setPriority(Thread.MIN_PRIORITY);
Iterator it = svgDocumentLoaderListeners.iterator();
while (it.hasNext()) {
nextDocumentLoader.addSVGDocumentLoaderListener
((SVGDocumentLoaderListener)it.next());
}
startDocumentLoader();
}
});
}
Can anyone help me get out of this mess, please?
Thanks in advance!
Finally solved the issue. Extended JSVGCanvas, override the createUserAgent() method to provide a bridgeuseragent of my own. This useragent extends the JSVGCanvas user agent but overrides the displayError methods. Here's the code:
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.swing.JSVGCanvas;
import org.apache.batik.util.XMLConstants;
/**
*
* #author
*/
public class myJSVGCanvas extends JSVGCanvas{
#Override
protected UserAgent createUserAgent() {
return new myCanvasUserAgent();
}
protected class myCanvasUserAgent extends CanvasUserAgent
implements XMLConstants {
/**
* Displays an error message in the User Agent interface.
*/
#Override
public void displayError(String message) {
if (svgUserAgent != null) {
super.displayError(message);
} else {
System.out.println(message);
// JOptionPane pane =
// new JOptionPane(message, JOptionPane.ERROR_MESSAGE);
// JDialog dialog =
// pane.createDialog(myJSVGCanvas.this, "ERROR");
// dialog.setModal(false);
// dialog.setVisible(true); // Safe to be called from any thread
}
}
/**
* Displays an error resulting from the specified Exception.
*/
#Override
public void displayError(Exception ex) {
if (svgUserAgent != null) {
super.displayError(ex);
} else {
ex.printStackTrace();
// JErrorPane pane =
// new JErrorPane(ex, JOptionPane.ERROR_MESSAGE);
// JDialog dialog = pane.createDialog(myJSVGCanvas.this, "ERROR");
// dialog.setModal(false);
// dialog.setVisible(true); // Safe to be called from any thread
}
}
}
}
Hope it helps somebody. If anyone has a better idea for dealing with the problem, than just hiding it, I'd be glad to hear it!

Java Midi - How To Create Midi Events / Record from Java Synth to Java Sequencer?

I will start off by explicitly stating my main question: what is the correct way to create midi events with the correct 'tick' from ShortMessages with the correct microsecond position when using the Java synthesizer to record to the Java sequencer?
I've been trying to figure this out for several days. My little midi program is quite simple, or should be, at least. There's a piano layout and three buttons. The piano, which uses the synthesizer, works great; you can play notes with the mouse or your computer keyboard.
I've read the Oracle Docs instructions backwards and forwards (and lots of forum threads), but clearly I'm missing something.
Currently I can get the sequencer to record by manually creating a ShortMessage, a MidiEvent, and sending them to the sequencer/add them to the track, but it will only record once. The play back also plays them back with usually the wrong timing. Here's the code that executes these: (if you want me to post additional or all of the code let know).
The code for what happens when I click the record/stop/buttons:
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand() == "Record")
{
mySeq.deleteTrack(track);
track = mySeq.createTrack();
try {
seq.setSequence(mySeq);
} catch (InvalidMidiDataException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
seq.recordEnable(track, ChannelNum);
seq.startRecording();
}
else if(e.getActionCommand() == "Stop")
{
seq.stop();
}
else if(e.getActionCommand() == "Play")
{
mySeq.deleteTrack(track);
track = mySeq.createTrack();
addEvents(track);
seq.setTickPosition(10);
seq.start();
}
}
This is the code for when the user plays a note on the piano:
// The Mouse presses a key, the note on the channel is turned on
// A MidiEvent and ShortMessage are created using the CreateOnEvent method
public void mousePressed (MouseEvent e) {
Key key = (Key) e.getSource ();
channel.noteOn (key.getNote (), 127);
CreateOnEvent(key);
}
public void mouseReleased (MouseEvent e) {
Key key = (Key) e.getSource ();
channel.noteOff (key.getNote ());
CreateOffEvent(key);
}
public void mouseClicked (MouseEvent e) { }
public void mouseEntered (MouseEvent e) { }
public void mouseExited (MouseEvent e) { }
And finally here's the CreateOnEvent Method:
// I originally was sending the events directly to the sequencer
// but here I'm adding the events to an ArrayList of MidiEvents to attempt a work around
// I can then add those events to a track to play them
public void CreateOnEvent(Key key)
{
if(seq.isRecording())
{
ShortMessage myMsg = new ShortMessage();
try {
myMsg.setMessage(ShortMessage.NOTE_ON, ChannelNum, key.getNote(), 127);
} catch (InvalidMidiDataException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
long timeStamp = synth.getMicrosecondPosition();
long tick = seq.getTickPosition();
event = new MidiEvent(myMsg, tick);
seqReceiver.send(myMsg, timeStamp);
Events.add(event);
}
}

Categories

Resources