I'll start by saying that I'm a bit new to java, so if it's a stupid mistake, that's the reason.
I was messing with applets in java, and I've run into a problem when setting the size of the window, and using JOptionPane, whether it's just showing a message, or getting input through it, it displays three or more panes, rather than simply one. I'm on Ubuntu 12.04(x64), and here is my test code that still encounters the problem:
import javax.swing.JOptionPane;
import java.awt.Graphics;
import java.applet.Applet;
public class Main extends Applet{
public void paint(Graphics g)
{
//setup screen size
setSize((int)500,(int)500);
//print test message
JOptionPane.showMessageDialog(null, "There Should Be One Of Me!");
}
}
That's expected: there are as many option panes as number of calls to the paint method :-) the latter is not controllable by application code, neither in AWT nor in Swing.
As a general rule, never-ever change any component state in methods called during the paint cycle
remove setSize(.. and JOptionPane.sh... from public void paint(Graphics g)
for Applet I miss there method init()
(J)Applet tutorial shows a few examples
maybe better could be to use Swing JFrame instead of (J)Applet
Related
I'm making a simple tool with Processing 3.
I want my sketch to not close when the "X" button is pressed. I found a question here on StackOverflow, but when I try doing that, I have this error: ClassCastException: processing.core.PApplet$8 cannot be cast to javax.swing.JFrame
I've tried adding more libraries, but now the error says is non a library error.
Here a piece of code:
import javax.swing.JFrame;
void setup() {
size(640, 360);
((JFrame)frame).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
void draw() {
textSize(50);
text("some text", width/2, height/2)
}
void exit() {
println("Not exiting");
}
When I try to run the sketch I have the error ClassCastException: processing.core.PApplet$8 cannot be cast to javax.swing.JFrame
The answer you linked to is for Processing 2, but you're using Processing 3.
Your error says it all: frame cannot be cast to JFrame, which is what you're trying to do here:
((JFrame)frame).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
To understand the source of this error, you can look at the source for the PApplet class here.
Do a search for "frame" in that file to see that the frame variable is now a java.awt.Frame instead of a javax.swing.JFrame. Processing also overrides some of the functions in the java.awt.Frame to provide Processings-specific behavior and warning messages.
You could start researching how to prevent a java.awt.Frame from closing, but I'd also consider rethinking whether you want to do this at all. Preventing windows from closing is a bit of an anti-pattern, so you should think carefully about whether you really need to do this. You could also consider other options, such as using a full-screen window rather than an uncloseable one.
I am unable to understand why the println() statement inside paint() is executing twice.This is the code-
import java.awt.*;
import java.applet.*;
public class FirstApplet extends Applet
{
public void init()
{
System.out.println(getBackground());
}
public void paint(Graphics g)
{
setBackground(Color.CYAN);
setForeground(Color.RED);
g.drawString("This is my first Applet",250,250);
System.out.println(getBackground());
}
}
OUTPUT:
java.awt.Color[r=255,g=255,b=255]
java.awt.Color[r=0,g=255,b=255]
java.awt.Color[r=0,g=255,b=255]
Can somebody please explain me why the println() inside paint() is executing twice?
public void paint(Graphics g)
{
setBackground(Color.CYAN); // will trigger repaint()!
setForeground(Color.RED); // will trigger repaint()!
g.drawString("This is my first Applet",250,250);
System.out.println(getBackground());
}
The paint(Graphics) method is called whenever the toolkit feels it is necessary to do so. There are many things that will cause a repaint() (which in turn, leads to a call to paint(Graphics)). Some of them are:
A window moves in front of, or is removed from in front of, the app.
The size of the app. changes.
The background or foreground color changes or a component state changes.
A menu opens or closes.
...
Obviously, a paint does not happen only the times the programmer wants (or expects) it to. If that 'paint whenever needed' is a problem for the app., it is the apps. problem to sort, not the toolkits.
Queries for you:
Why code an applet? If it is due to the teacher specifying it, please refer them to Why CS teachers should stop teaching Java applets.
Why use AWT? See this answer for many good reasons to abandon AWT using components in favor of Swing.
I use NetBeans for Java programming, and whenever I try to make an Applet, it doesn't work. The code is completely correct and I did not make any mistakes on it. When I hit "Run" a message appears in the output box that says, "BUILD SUCCESSFUL (total time: 0 seconds)" There are no error messages and no errors in the code, the Applet doesn't appear. The code is:
import java.applet.*;
import java.awt.*;
public class myProject extends Applet
{
public void init()
{
}
public void paint(Graphics g)
{
setSize(500,500);
}
public static void main(String[] args)
{
}
}
Get rid of the main method. If you're running the code as an applet, main will just confuse you and the IDE.
Make sure that you're telling NetBeans to run it as an applet, not as an application. Again, removing main should help you with this, since without main it can't run it as an app.
Consider not creating applets since they're considered somewhat dead technology.
Don't have setSize(...) within a paint method. Ever. GUI painting methods, such as paint(...) for AWT components and paintComponent(...) for Swing components derived from JComponent, should just do painting and nothing else.
Check out the Java Swing tutorials which can be found here: Swing Info
I am having trouble getting message boxes and to a degree dialog boxes to show/function properly in Mac (v10.9.5).
I just updated the JRE and JDK to the latest version (8u31). A "java -version" from a terminal window shows that I am indeed using 8u31. (I was previously using 8u20, which exhibited the same behavior.)
The code below works perfectly in Windows and a couple of different versions of Linux that I tested, no issues. I just have issues on a Mac. I streamlined my code, which is SWT based, but this example uses Swing, to the following:
package myTest;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class EntryCode
{
public static EntryCode oEntryCode;
public EntryCode()
{
// TODO Auto-generated constructor stub
}
public static void main(String[] args)
{
oEntryCode = new EntryCode();
oEntryCode.open();
}
public void open()
{
JPanel panel = new JPanel();
panel.setMinimumSize(new Dimension(200,200));
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
}
I see the first system out line, and the code hangs on the message box request. In the real code, I simply use a null as the first argument. The original version of this test code used a null too, just I was experimenting with specifying a component. I thought that might be the problem. It is not.
When displaying SWT dialog boxes, there is a tendency that clicking on a button will hang the interface. The hang is somewhere between the button being depressed and the event handler firing. The event handler never fires.
I did not include a dialog box here. I figure that since my confirmation/message box exhibits the same problem that solve one, get the other for free.
I did a search on Google for displaying java applications on a Mac, but nothing turned up.
I would think that updating the JRE/JDK to the latest version would solve any OS related issues.
I compile the code to a jar and use the following to run from a terminal window. I to press Ctrl+C to quite the hung app.
java -XstartOnFirstThread -jar myTest.jar
Thoughts?
UPDATE:
I deleted the original update but am leaving the original question, now that I understand the problem better.
The real problem is how to initiate a proper Mac OSX Cocoa restriction friendly SWT application, which uses dialog and message boxes. (To the best of my knowledge, the only way to display message boxes is to use JOptionPane.show*, which is a Swing thing, thereby sort of mixing Swing and SWT.
It is interesting to note that the problem always relates to buttons, be it on a dialog box (a purely SWT implementation) or message boxes. In the former, the issue is a hang calling the event handler and the latter displaying a message box (null first argument, as no Swing frame exists in a SWT application).
The problem may be that you are not starting the GUI in the EDT. Try this:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
oEntryCode = new EntryCode();
oEntryCode.open();
}
});
}
More info: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
Another issue is using -XstartOnFirstThread with Swing. Swing does the equivalent of what -XstartOnFirstThread is doing, but in its own way. You should not use -XstartOnFirstThread with Swing, just as it's not a good idea to mix SWT and Swing.
If you add SwingUtilities.invokeLater() and remove -XstartOnFirstThread, your example should run normally.
Not quite sure if this might be the error since I can't test it on my Mac at the moment. But you never setting visibility of the JFrame to true. When you pass the frame as a parameter to the JOptionPane the pane tries to show the pane in the frame.
So try :
public void open()
{
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
frame.setSize(300,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
Also why do you create the JPanel the panel is never used as far as I can see ?
Since the frame is not visible this could cause problems. Just a guess...
This would also explain why it looks like your application is "freezing". Its because it is waiting for you to make the selection in your JOptionPane but you can't make that selection because you can't see the JOptionPane.
I know you wrote you also tried with passing null as argument but I could think this could also cause problems when there is no other JFrame shown. As i said just a guess. Just try it out and come back here to provide further information.
EDIT
Just tested and looks like your code is fine. Your error has to lie in your mac or java setup.
EDIT 2
I think I found your answer. Looks like the startOnFirstThread is the problem here. I just tested via javac and java on command line. Have a look at this:
Swing stops working, because -XstartOnFirstThread implies that that
someone else (very likely the SWT) is going to come around, and start
pumping the event loop on thread 0 with CFRunLoop or the like
This could explain why your JOptionPane struggles to show up. (Taken from: here
Also a bit older but describes your problem:
The AWT problems generally come down to which thread the jvm was started on. When using the java launcher (as pde does) on Mac, java by default starts on the second thread (which is what AWT wants) unless you specify -XstartOnFirstThread (which is what SWT wants).
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=212617)
I've made a game in Java which works without any problem when I run it in Eclipse. Everything looks great and it is effectively done (at least until I come up with something else to do with it). So I've been trying to put it on my website, but whenever I run the game in browser I simply get a white screen, though checking the Java console shows no errors. I've managed to narrow the problem down to the painting of the screen. I have a timer which runs the game and makes stuff happen. At the end of it, it calls the repaint() method. In Eclipse, that works fine, but in the browser, nothing happens.
Here's the relevant code (All of which is inside the main class called FinalProject):
public class FinalProject extends JApplet implements ActionListener,
KeyListener, MouseListener, MouseMotionListener {
public void init(){
//...initialize program
System.out.println("game started");
}
/**
* A method called every so often by a timer to control the game world.
* Mainly calls other functions to control objects directly, but this
* is used as the only timer, which also calls repaint() at it's end.
*/
private void runGame(){
//...Run game and do important stuff
//This Draws The Screen
System.out.println("about to paint");
repaint();
}
public void paint(Graphics g){
System.out.println("painting");
//...paint screen
}
public void update(Graphics gr){
System.out.println("updating");
paint(gr);
}
}
runGame() is called by a timer. In Eclipse the output is:
game started
painting
painting
about to paint
painting
about to paint
painting
about to paint
painting
...
When doing this in a browser (Running offline directly on my machine. All browsers have the same problem as well), the console shows:
...(loading stuff)
game started
basic: Applet initialized
basic: Starting applet
basic: completed perf rollup
basic: Applet made visible
basic: Applet started
basic: Told clients applet is started
about to paint
about to paint
about to paint
...
I don't know what else to try at this point. Despite my efforts I still don't fully understand exactly what repaint() does, all I know is that it ultimately calls update() and paint(). Except that doesn't seem to be happening in the browser. I'm using Windows 7 64x with Java Version 7 Update 5. Thanks in advance for any help.
Turns out, the problem was in removing the menu bar. I had found some code a while ago which would remove the menu bar from the program and it worked without any problems. However it seems that it prevented it from repainting when placed in a browser. I have no idea why repainting broke because of removing the menu bar, but apparently it does.
The code I had used (in init()):
Frame[] frames = Frame.getFrames();
for (Frame frame : frames){
frame.setMenuBar(null);
frame.pack();
}
This code did remove the menu bar as desired, but also exploded the program whenever it was put online. Removing this fixed the issue. Fortunately, the menu bars don't show up online anyways, so you aren't losing much by removing this bit of code.