How to close new frame without exiting whole application?
What is easiest way to do it by clicking X button.
Thanks in advance.
ControlFrame cf;
void setup()
{
cf = new ControlFrame(this,500,500, "cf name");
}
class ControlFrame extends PApplet
{
int w,h;
PApplet parent;
public ControlFrame(PApplet _parent, int _w, int _h, String _name)
{
super();
parent=_parent; w=_w; h=_h;
PApplet.runSketch(new String[]{this.getClass().getName()},this);
}
public void settings()
{ size(w,h); }
}
Note: Your question doesn't really have anything to do with ControlP5.
Step 1: Get a reference to the native window. How you do this depends on the renderer you're using. If you're using the default renderer, it looks like this:
Frame frame = ( (SmoothCanvas) ((PSurfaceAWT)surface).getNative()).getFrame();
Step 2: You can then call dispose() on that Frame to hide it without quititng the entire application.
frame.dispose();
Putting it all together, it looks like this:
import java.awt.Frame;
import processing.awt.PSurfaceAWT;
import processing.awt.PSurfaceAWT.SmoothCanvas;
ControlFrame cf;
void setup()
{
cf = new ControlFrame(this, 500, 500, "cf name");
}
class ControlFrame extends PApplet
{
int w, h;
PApplet parent;
public ControlFrame(PApplet _parent, int _w, int _h, String _name)
{
super();
parent=_parent;
w=_w;
h=_h;
PApplet.runSketch(new String[]{this.getClass().getName()}, this);
}
public void settings()
{
size(w, h);
}
public void draw(){
//needed for mousePressed
println(millis());
}
public void mousePressed(){
Frame frame = ( (SmoothCanvas) ((PSurfaceAWT)surface).getNative()).getFrame();
frame.dispose();
}
}
Step 3: Note that your second sketch will continue running, so you might also want to call noLoop() to prevent unnecessary computation.
Related
I'm trying to work with the Java paint
utility and it's been a bit of a hassle.
I'm trying to do something which I assume is quite basic.
I'm drawing a square Graphic to a JPanel and then trying
to move it using repaint
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class testGui {
static gui gc_gui;
static int gv_x;
static int gv_y;
public static void main(String[] args) {
gc_gui = new gui();
gv_x = 50;
gv_y = 50;
gc_gui.cv_frame.setVisible(true);
}
public static class gui {
JFrame cv_frame;
content cv_content;
public gui() {
cv_frame = new JFrame();
cv_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cv_frame.setTitle("Test GUI");
cv_frame.setSize(600, 400);
cv_frame.setLayout(new FlowLayout());
cv_content = new content();
cv_content.setBackground(Color.Black);
cv_content.setPreferredSize(new Dimension(500, 300));
cv_frame.add(cv_content);
gv_x = 0;
gv_y = 0;
cv_content.update();
}
}
public static class content extends JPanel {
public void paint(Graphics graphic) {
super.paint(graphic);
draw(graphic);
}
public void update() {
super.repaint();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.setPaint(Color.Red);
graphic2D.fillRect(gv_x, gv_y, 100, 100);
}
}
}
I don't know why the call to the update function isn't doing
anything though.
It draws the square at 50x and 50y, the sets it to 0x and 0y
immediately and then when I call repaint I expected it to
be moved to it's new coordinates although it's still at
50x and 50y.
Why is this?
Your solution is to use KeyBindings.
https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
and also.
You need to create a Swing Timer, Thread, or Loop , that manages the frames to be painted. and such
Here is a link for Swing Timers as they are pretty easy to implement:
https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html
A lot of programs I see also have this ( AKA. working with threads.):
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
I'm trying to make a child class from JFrame. I think im doing it correctly but when I run this it opens a blank window without a name or background color (my JPanel class does the background. However, I know the error is not there because I commented out the add(Jpanel) and the window still didn't have a name) Also eclipse doesn't show any syntax errors. Why doesn't this code work?:
Main Class:
package ashwin.engine;
import javax.swing.*;
import java.awt.*;
public class Execute {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
int[] bcolor = new int[3];
bcolor[0] = 254;
bcolor[1] = 0;
bcolor[2] = 0;
Window wndw = new Window("Test", 1000, 1000, bcolor, true);
} });
}
}
JFrame Child Class:
package ashwin.engine;
import javax.swing.*;
import java.awt.*;
public class Window extends JFrame {
Window(String name, int width, int length, int[] backgroundColor, boolean visible) {
System.out.println("made it to frame class");
setName(name);
setVisible(visible);
setSize(width, length);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Display display = new Display(backgroundColor);
}
}
edit:
Forgot to mention, it does print out my debug statement "made it to frame class", dont know if that helps but I thought I should point it out.
You shouldn't use setName but setTitle. This will effectively display the name on the screen.
For the background, you should use getContentPane().setBackgroundColor(Color color)
The chode should look like this:
public class Execute {
public static void main(final String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
final Color bcolor = new Color(254, 0, 0);
final Window wndw = new Window("Test", 1000, 1000, bcolor, true);
}
});
}
}
public class Window extends JFrame {
Window(final String name, final int width, final int length, final Color backgroundColor,
final boolean visible) {
System.out.println("made it to frame class");
this.setTitle(name);
this.setSize(width, length);
this.getContentPane().setBackground(backgroundColor);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(visible);
}
}
Make the setVisible line the last line.
I'm starting to learn to create Games in Java, and one of the methods I'm using includes BufferedImage. This is the error I get:
"Exception in thread "main" java.lang.NullPointerException
at tm.Game.init(Game.java:48)
at tm.Game.<init>(Game.java:54)"
From this code:
package tm;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Game extends JPanel implements Runnable {
private Settings Settings;
private Thread t;
private BufferedImage offscreenImage;
private Graphics offscr;
public void run() {
while(true) {
repaint();
try {
Thread.sleep(1000/30);
} catch (InterruptedException e) { }
}
}
public void paint(Graphics g) {
offscr.setColor(Color.blue);
offscr.fillRect(0, 0, Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr.setColor(Color.white);
offscr.drawString("Lolz", 10, 10);
g.drawImage(offscreenImage, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public void init() {
t = new Thread(this);
t.start();
offscreenImage = (BufferedImage) createImage(Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
}
public Game() {
Settings = new Settings();
init();
}
}
Settings Class:
package tm;
public class Settings {
public final int GAME_WIDTH = 500;
public final int GAME_HEIGHT = 500;
}
Screen Class:
package tm;
import javax.swing.JFrame;
public class Screen extends JFrame {
private static final long serialVersionUID = 1L;
private JFrame mainScreen;
private Game mainGame;
private Settings Settings;
public Screen() {
mainGame = new Game();
Settings = new Settings();
mainScreen = new JFrame();
mainScreen.add(mainGame);
mainScreen.setSize(Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
mainScreen.setTitle("Lolz");
mainScreen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainScreen.setResizable(false);
mainScreen.setVisible(true);
}
public static void main(String[] args) {
new Screen();
}
}
It is not getGraphics() that returns null but rather the previous function createImage(). From the Component documentation for createImage():
returns an off-screen drawable image, which can be used for double
buffering. The return value may be null if the component is not
displayable. This will always happen if
GraphicsEnvironment.isHeadless() returns true.
You then get a NullPointerException when calling getGraphics() on offscreenImage which is null.
The reason that throw NullPointer exception is that you initialized the offScreenImage and offScr in wrong place.
offscreenImage = (BufferedImage) createImage(Settings.GAME`WIDTH, Settings.GAME_HEIGHT);
offscr = offscreenImage.getGraphics();
This code should be in the function paint. To get the results the Game class should be defined like this. And another tip it is better to declare variables inn Settings class to public static final so that they can be accessed in static way. Make little change to your Game class as defined below. I think this should help you.
package tm;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import tm.Screen.Settings;
public class Game extends JPanel implements Runnable {
// private Setting Settings;
private Thread t;
private BufferedImage offscreenImage;
private Graphics offscr;
public void run() {
while (true) {
repaint();
try {
Thread.sleep(1000 / 30);
} catch (InterruptedException e) {
}
}
}
public void paint(Graphics g) {
if (offscreenImage == null) {
offscreenImage = (BufferedImage) createImage(Settings.GAME_WIDTH,
Settings.GAME_HEIGHT);
}
offscr = offscreenImage.getGraphics();
offscr.setColor(Color.black);
offscr.fillRect(0, 0, Settings.GAME_WIDTH, Settings.GAME_HEIGHT);
offscr.setColor(Color.white);
offscr.drawString("Lolz", 10, 10);
g.drawImage(offscreenImage, 0, 0, this);
}
public void update(Graphics g) {
paint(g);
}
public void init() {
t = new Thread(this);
t.start();
}
public Game() {
init();
}
}
Since createImage only works after the Component is "displayable" e.g. it is attached to a visible JFrame your current code wont work.
There are several ways you can deal with it.
Add JFrame as a parameter to the ctor and add the Game to the JFrame before calling create component - this should work as long as JFrame.add does not call any methods overridden by the partially initialized Game instance.
Game(JFrame jf){
jf.add(this);
...
}
JFrame mainFrame = new JFrame();
mainFrame.setVisible(true);
Game game = new Game(mainFrame);
Make an additional init method which is called after adding Game to the JFrame. This is ugly since the Game object is not really fully initialized until this method is called.
Game game = new Game();
JFrame mainFrame = new JFrame();
mainFrame.add(game);
mainFrame.setVisible(true);
game.init();
One way to find out when the component is displayable is to listen for a HierarchyEvent. You could modify the Listener shown in the answer to call createImage instead of printing "showing". (The class provided by that answer also needs a extends HierarchyListener to work)
Please have a look at the following code
First, Please note I am a 100% newbie to Java Mobile.
In here, I am making the light on and vibrate on when user click the button. However, I really wanted to create a SOS application which turn the whole screen into white, and go to black, like that, in the thread. I guess I didn't achieve that by this app because even the lights are on, the buttons are still there. I tried to turn the "Form" color to "white" but it seems like JME has no "Color" class.
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Midlet extends MIDlet{
private Form f;
private Display d;
private Command start,stop;
private Thread t;
public Midlet()
{
t = new Thread(new TurnLightOn());
}
public void startApp()
{
f = new Form("Back Light On");
d = Display.getDisplay(this);
d.setCurrent(f);
start = new Command("Turn On",Command.OK,0);
stop = new Command("Turn Off",Command.OK,1);
f.addCommand(start);
f.setCommandListener(new Action());
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional)
{
this.notifyDestroyed();
}
private class Action implements CommandListener
{
public void commandAction(Command c, Displayable dis)
{
f.append("Light is Turnning On");
t.start();
}
}
private class ActionOff implements CommandListener
{
public void commandAction(Command c, Displayable dis)
{
}
}
private class TurnLightOn implements Runnable
{
public void run()
{
f.append("Working");
for(int i=0;i<100;i++)
{
try
{
d.flashBacklight(200);
d.vibrate(200);
Thread.sleep(1000);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
Use the javax.microedition.lcdui.Canvas instead of Form. This example can get you started
public void startApp()
{
f = new Form("Back Light On");
d = Display.getDisplay(this);
start = new Command("Turn On",Command.OK,0);
stop = new Command("Turn Off",Command.OK,1);
f.addCommand(start);
f.setCommandListener(new Action());
myCanvas = new MyCanvas();
d.setCurrent(myCanvas);
myCanvas.repaint();
}
Now create a canvas and implement paint method like this:
class MyCanvas extends Canvas {
public void paint(Graphics g) {
// create a 20x20 black square in the center
// clear the screen first
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(0xffffff); // make sure it is white color
// draw the square, <b>changed to rely on instance variables</b>
<b>g.fillRect(x, y, getWidth(), getHeight());</b>
}
}
I need a listener that will constantly check if a static boolean value has been changed so that I can repaint a component on a frame. Can someone please help me I really don't know much about listeners and haven't worked with them much? Help will be greatly appreciated.
edit(more clarity): I have two separate classes in which on class is the "main frame" the second class is an extension of JLabel and implements MouseListner for a "clickable photo". The "main frame" creates instances of the photo and when the photo is clicked the "main frame" is supposed to paint on the panel a description of the photo. This is "main frame"
MenuBar menuBar;
static AnnotationVisual a;
Picture pic;
Picture pic2;
GalleryScreen(int rows, int columns){
this.setBorder(BorderFactory.createEmptyBorder(500,500,0,0));
pic = new Picture("pic1", "Z:/My Documents/Downloads/Ball.jpg", new Coordinate(0,0));
pic2 = new Picture("pic2", "Z:/My Documents/Downloads/hoop.jpg" , new Coordinate(1,0));
this.add(pic);
this.add(pic2);
a = new AnnotationVisual();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(a.shouldAnnotate()){
FontMetrics size= g.getFontMetrics();
if(getWidth()>=(a.dispX()+size.stringWidth(a.annotationText()))){
g.setColor(Color.white);
g.fillRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15);
g.setColor(Color.black);
g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15);
g.drawString(a.annotationText(), a.dispX(), a.dispY());
}else{
String sub="";
int letters=0;
g.setColor(Color.white);
g.fillRect(a.dispX()-3,a.dispY()-12,getWidth(),15);
g.setColor(Color.black);
for(int i=0;i<a.annotationText().length();i++){
if(a.dispX()+letters+16<=getWidth()){
sub+=a.annotationText().substring(i,i+1);
letters=size.stringWidth(sub);
}else{
sub=sub+"...";
i=a.annotationText().length();
}
}
g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(sub)+3,15);
g.drawString(sub,a.dispX(),a.dispY());
}
}
}
public static AnnotationVisual getA()
{
return a;
}
This is "clickable photo"
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.*;
import javax.swing.*;
public class Picture extends JLabel implements MouseListener
{
String myAnnotation;
String filePath;
Coordinate imageCoord;
private boolean wasDoubleClick;
private Timer timer;
EditAnnotation newEdit;
AnnotationVisual newVisual;
public Picture(String annotation, String filePath, Coordinate coord)
{
super(new ImageIcon(filePath));
this.addMouseListener(this);
myAnnotation=annotation;
this.filePath = filePath;
imageCoord = coord;
newEdit = new EditAnnotation(annotation);
newVisual = new AnnotationVisual();
}
public Picture(String filePath)
{
super(new ImageIcon(filePath));
this.addMouseListener(this);
this.filePath = filePath;
newEdit = new EditAnnotation();
newVisual = new AnnotationVisual();
}
public String getAnnotation()
{
return myAnnotation;
}
public AnnotationVisual getAnnotationVisual()
{
return newVisual;
}
public void setAnnotation(String annotation)
{
myAnnotation=annotation;
}
public Coordinate getCoordinate()
{
return imageCoord;
}
public void setCoordinate(Coordinate coord)
{
imageCoord = coord;
}
public Dimension getSize()
{
return new Dimension(super.getIcon().getIconWidth(), super.getIcon().getIconHeight());
}
public void mouseClicked(MouseEvent e)
{
final int scrLocX = (int)e.getLocationOnScreen().getX();
final int scrLocY = (int)e.getLocationOnScreen().getY();
if (e.getClickCount() == 2)
{
wasDoubleClick = true;
}
else if(e.getClickCount() == 1)
{
Integer timerinterval = (Integer) Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");
timer = new Timer(timerinterval.intValue(), new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (wasDoubleClick)
{
GalleryScreen.getA().deleteAnnotation();
myAnnotation = newEdit.getAnnotation();
newEdit.show(myAnnotation);
wasDoubleClick = false;
}
else
{
GalleryScreen.getA().deleteAnnotation();
GalleryScreen.getA().showAnnotation(scrLocX, scrLocY , myAnnotation);
}
}
});
timer.setRepeats(false);
timer.start();
}
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
}
AnnotationVisual is the thing that supposed to pop up when single clicked
You're probably better off making the boolean private, and only allowing it to be changed through a setter method. The setter method, when called, should then repaint the component.
The point of listeners is to invert the logic. You don't constantly check if a value is changed. You notify the listener when you change the value.
So, instead of Foo.bar = 5, you invoke Foo.setBar(5), where in addition to the assignment, you call barListener.valueChanged(value)
As a sidenote - avoid storing state in static variables.
You don't set a listener on a field in Java, you set it on a property. While properties (according to the JavaBeans spec) can be fields, they're usually done as pairs of methods (one getter, one setter; the latter being not needed for read-only fields) as that lets you hook extra logic in to be called when the property is accessed. Such as firing a listener callback to say that the value has changed. (You could use a thread to monitor for that sort of thing, but that's really nasty and error-prone. Wasteful too.)
One thing to be aware of though: you don't know what thread the value will have been modified from. Take care when invoking back into Swing…