So I programmed am applet that makes a ball roll in circles for ever, and I wanted to make the user decide what speed the circle should roll in, but something failed when I added the JFrame:
applet(the stop,destroy and update do not appear because they aren't important, and in start there is nothing):
public class Main extends Applet implements Runnable{
private Image I;
private Graphics GfU;
int ballX, ballY=249;
static int radius=20;
double Memory;
int changeY ,changeX=1;
Speed S = new Speed();
#Override
public void init() {
setSize(750,750);
S.setVisible(true);
}
#Override
public void run() {
while(true){
if(ballY>=250 || ballY<=-250){
changeY=0-changeY;
changeX=0-changeX;
}
ballY+=changeY;
Memory=(double)ballY/250;
Memory=Math.asin(Memory);
Memory=Math.cos(Memory);
ballX=(int)(Memory*250);
if(changeX==-1)
ballX=0-ballX;
repaint();
try {
Thread.sleep(17);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void paint(Graphics g) {
g.setColor(Color.black);
g.fillOval(ballX-radius+250, ballY-radius+250, radius*2, radius*2);
}
public void setChangeY(int changeY) {
this.changeY = changeY;
}
public void Done(){
S.setVisible(false);
Thread BallRun = new Thread(this);
BallRun.start();
}
}
JFrame:
public class Speed extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
public Speed(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel P = new JPanel();
JLabel L = new JLabel("please enter velosity(pixels per second)");
final JTextField TF = new JTextField("00");
final Main M = new Main();
JButton B = new JButton("OK");
B.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
M.setChangeY(Integer.parseInt(TF.getText()));
M.Done();
}
});
P.add(L,BorderLayout.NORTH);
P.add(TF,BorderLayout.WEST);
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
}
thanks (and sorry if it's bothering you the lack of information)
Here are some things to consider:
Don't use a JFrame. Use a JDialog as a popup window. Also, you should probably not create the dialog in the constructor. Instead you should have a JMenuItem so that the user can click on the menu when they want the popup to display.
Don't use "Applet", that is an AWT component. You should be using "JApplet" in a Swing application.
You should not be overriding the paint() method of the applet. Instead you should be adding a JPanel to the applet and then override the paintComponent(...) with your custom painting.
Don't use a loop to control the animation. Instead you should be using a Swing Timer.
Start by reading the Swing tutorial. There are sections on:
How to Make Applets
How to Use Swing Timers
Performing Custom Painting
setDefaultCloseOperation(EXIT_ON_CLOSE);
This is not allowed even in a fully trusted applet. Closing the frame would close the JVM that runs the applet that launched it. That JVM might also be running other applets.
Look at it like this. The web page that hosts an applet is like a guest, while the web page is a guest house. For an applet to end the JVM is like the guest burning down the guest house while smashing out all the windows.
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
Might 'work' (to not produce an AccessControlException), but really, no applet should be launching frames. Use a JDialog instead.
As a general tip: Ensure the Java Console is configured to show for applets & JWS apps. If there is no output at the default level, raise it and try again. Without the information contained in it, I doubt it would be possible to successfully develop an applet.
Your Speed class extends JFrame, but the only things that you set is setDefaultCloseOperation(EXIT_ON_CLOSE), you should set at least se size of your JFrame with setSize(width, height) and set it visible with: setVisible(true).
Another thing... i can't see where you added your JFrame to the Main class...
You should add it creating a new Speed object: Speed objectname = new Speed()
If i've understood correctly that was your problem.
I think you could read here to learn how to use the JFrame: http://www.dreamincode.net/forums/topic/206344-basic-gui-in-java-using-jframes/
Related
I have a jframe object in a class and I want to be able to close the frame from my jpanel class(which obviously I attach to the frame). Anyway, I tried making a instance field in my jpanel with the jframe object has an instance field and then made a method that I would call in the jframe class with the parameter of the jframe object I made so I could make the jpanel instance field the same object as the jframe object. I then called the instance field.dispose(); hoping it would close the frame. Any ideas would be greatly appreciated!
In case that was hard to understand here is an example:
public class example extends jFrame
{
public static void main(String[]args)
{
examplePanel ep = new examplePanel();
example e = new example(ep);
}
/**
* Constructor for objects of class example
*/
public example(examplePanel ep)
{
//code that handles my frame settings
}
}
public class examplePanel extends jPanel implements ActionListener
{
private example e;
private boolean checkWin;
public void actionPerformed(ActionEvent e)
{
if(this.checkWin())
{
setVisible(false);
e.dispose();
//^this line of code is supposed to dispose of the frame but it does not
}
}
public void getExample(example e)
{
this.e = e;
}
}
Your code and question are hard to follow as you have an ActionListener which you add to no JButton or JMenuItem, You create a JFrame object and a JPanel, but are never observed to add the panel to the frame. You give your JPanel an "example" variable, but never assign it a reference to the visualized JFrame, you don't appear to ever set the default close operation of the JFrame, and so your JFrame as written above should be non-closable. From your code it looks like your examplePanel's e variable in the JPanel should in fact be null and so calling any method on it should throw a NullPointerException, that is unless you're assigning the correct JFrame object reference to it, but are not showing us.
Myself, I'd get the top level window from Swing itself when needed, something like:
#Override
public void actionPerformed(ActionEvent e) {
// get the top-level window that is displaying this JPanel
Window win = SwingUtilities.getWindowAncestor(this);
if (win != null) {
win.dispose(); // dispose of it
}
}
For example:
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.*;
import javax.swing.*;
public class CloseFromJPanel extends JPanel implements ActionListener {
private static final int PREF_W = 400;
private static final int PREF_H = 300;
public CloseFromJPanel() {
JButton closeButton = new JButton("Close Me");
closeButton.addActionListener(this);
add(closeButton);
}
#Override
public void actionPerformed(ActionEvent e) {
// get the top-level window that is displaying this JPanel
Window win = SwingUtilities.getWindowAncestor(this);
if (win != null) {
win.dispose(); // dispose of it
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Close From JPanel");
// GUI will exit when the JFrame is closed
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new CloseFromJPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
This code will work for JButtons within JFrames and JDialogs, but not JMenuItems or within JApplets (I don't think). Or if all you want to do is end the application, then you could simply call System.exit(0) from within the actionPerformed method. If you absolutely want to do this using a field of the JFrame, then you'll need to pass in a reference to the JFrame into the JPanel, likely using a constructor parameter, and possibly passing in this.
If this doesn't help, please create and post real code, not kind-of sort-of code, code that we can compile, run and actually test, an MCVE (please check out the link).
Other issues:
Your code does not comply with Java naming standards as class names should all start with capital letters. Please Google this and study it, since if your code follows standards, others, including both us and your future self, will better be able to understand your code.
You'll rarely want to ever extend from JFrame since you rarely need to alter it's innate behavior. Usually you'll create and use a JFrame or JDialog when and where needed.
I'm having the following bug/problem and I havent been able to found solution yet on web or example of someone with similar issue.Basicaly I have a main frame that contains a panel of the same size(acting as the main panel) and When you press "Enter" an internal frame pop up(on top of where the playersprite is) acting as the inventory and then the control is passed to it and if you press "Enter" again the inventory is destroyed and control is passed back to the main panel.
the repaint function is called and the character and the map is then redrawn and this work about 90% of the time.The other 10% or less of time whenever the inventory is destroyed it seems the repaint is called(and work) except nothing is drawn its as if it draw on the destroyed panel because if I add a debug keypress that call repaint on the mainpanel(thescreen) everything is back to normal.
of course I could just repaint the character every loop in the run() method but thats terrible since I will only repaint if something changed(ie I moved)
I removed all the move and other code since they arent useful and still get the problem with the below code.You can think of the Character class as a plain drawn square.Anyone as any insight on why this is happening?
public class main extends JFrame implements Runnable{
private boolean gameRunning=true;
private Character Link;
private MainScreen theScreen;
public final int ScreenHeight=500;
public final int ScreenWidth=500;
public boolean inMenu=false;
Block ablock=new Block(200,200);
public class Inventory extends JInternalFrame{
public Inventory(){
setBounds(25,25,300,300);
setDefaultCloseOperation(HIDE_ON_CLOSE);
setVisible(true);
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
int key=e.getKeyCode();
if(key==KeyEvent.VK_ENTER){
try{
setClosed(true);
theScreen.requestFocusInWindow();
theScreen.repaint();
inMenu=false;
}
catch(Exception ex){}
}
}});
}
}
class MainScreen extends JPanel{
MainScreen(){
super();
setIgnoreRepaint(true);
setFocusable(true);
setBounds(0,0,ScreenWidth,ScreenHeight);
setVisible(true);
setBackground(Color.white);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Link.draw(g);
g.drawImage(ablock.getImg(),ablock.getX(), ablock.getY(),null);
}
}
main(){
super();
final JDesktopPane desk = new JDesktopPane();
theScreen=new MainScreen();
add(theScreen);
theScreen.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e){
int key=e.getKeyCode();
if(key==KeyEvent.VK_ENTER){
inMenu=true;
Inventory myInventory=new Inventory();
desk.add(myInventory);
myInventory.requestFocusInWindow();
}
}
});
add(desk);
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e) {}
setTitle("Project X");
setResizable(false);
Link=new Character();
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
main Game=new main();
new Thread(Game).start();
}
public void run(){
//omitted/irrelevant only contains a FPS count
}
}
}
Don't use KeyListeners. Use Key Bindings.
Don't use a Thread. Use a Swing Timer for animation so updates will be done on the EDT.
Don't use an Internal Frame for a popup window. Use a JDialog.
Do custom painting on a JPanel, not a JDesktopPane.
Don't use setIgnoreRepaints(). That is used for active rendering.
Don't use empty catch clauses.
Use standard Java naming conventions. Classes start with upper cases characters, variable names do not.
Don't use setBounds(). Use a Layout Manager.
I made a game that is based in a jpanel. When I add the jpanel to a jframe, it works fine on both pc's and macs.
here is the class where I add the jpanel to the jframe:
import javax.swing.JFrame;
public class Start{
public static void main(String[] args){
JFrame f = new JFrame("Rocks");
f.setSize(600,500);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Board b = new Board();
f.add(b);
f.setVisible(true);
}
}
However, when I add this jpanel to a japplet, it still works perfectly on pc's, but not on macs. In the eclipse applet tester, the first screen paints, but it doesn't accept keyboard input to start the game. In any browser/html page though, the game doesn't seem to load at all, and when I open the java console of chrome I see no errors.
here is the class where I add the jpanel to the japplet
import javax.swing.JApplet;
public class rockAppletStart extends JApplet{
public void init(){
Board b;
b = new Board();
add(b);
b.focus();
}
public void start(){}
public void stop(){}
public void destroy(){}
}
I would appreciate any help that could be offered, and I'm willing to provide more information if necessary. I could even provide the other classes of the game, but there very long and messy, and I'd rather not unless necessary.
The applet version of the game can be found here at gamejolt.com, if you feel like testing it out. If you have a pc, it should work fine, but with a mac it won't.
** edit **
here you can download the .jar file of all the classes and resources. Feel free to use the files to test out your solution yourself if you want... Otherwise, Ill have access to a mac on Tuesday and I will test all solutions then.
http://dl.dropbox.com/u/18832480/Rocks_Source_file.jar
This is just a SWAG, but since Swing threading issues can often cause pernicious, unpredictable and hard to detect errors, what if you create your applet in a thread-safe manner? i.e.,
public void init() {
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}
}
private void createGUI() {
Board b;
b = new Board();
getContentPane().add(b);
b.focus()
}
The JApplet is stealing the focus from the Board. To prevent it, add the following to the end of your init() method:
setFocusable(false);
I would like to create a JFrame with two specifal features:
JFrame should not grab focus while maximized from minimized state.
When a JFrame created or became maximized from minimized state, it should flash in the Windows bar until a user will grant a focus to it. (like as in ICQ clients ).
Does anybody know how the second requirement can be implemented?
Little self-explained example:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class JFrameTest {
private static JFrame childFrame;
public static Container getParentContentPane() {
JPanel panel = new JPanel();
JButton button = new JButton("Create\\Restore child frame");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
createOrRestoreChildFrame();
}
});
panel.add(button);
return panel;
}
private static void createOrRestoreChildFrame() {
if (childFrame == null) {
childFrame = new JFrame("Child Frame");
childFrame.setLocation(200, 200);
childFrame.add(new JLabel("Child Frame"));
childFrame.pack();
setChildFrameVisible();
} else {
setChildFrameVisible();
}
}
private static void setChildFrameVisible() {
childFrame.setFocusableWindowState(false);
childFrame.setVisible(true);
flashInWindowsBar(childFrame);
childFrame.toFront();
childFrame.setFocusableWindowState(true);
}
/**
* Should Make child frame flash in Windows bar.
* Currently, it does not work for me.
* Could anybody help me to fix this please? )
*/
private static void flashInWindowsBar(JFrame childFrame) {
childFrame.setState(JFrame.ICONIFIED);
childFrame.toFront();
}
private static void createAndShowGUI() {
JFrame parentFrame = new JFrame("JFrame Demo");
parentFrame.setLocation(100, 100);
parentFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
parentFrame.setContentPane(getParentContentPane());
parentFrame.pack();
parentFrame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
Thanks!
The following code worked for me exactly as you described:
f.setState(JFrame.ICONIFIED);
f.toFront();
f is a JFrame.
Unfortunately, this isn't something that you can do natively under any Java platform. Anyone who manages to get it working by using the kind of 'trickery' that you've shown, will be disappointed to find that it is unlikely to work on another version of Windows, or even another computer with the same version of Windows. The only times I've ever seen a Java window flash is due to some glitch in Swing when minimizing all windows to the taskbar.
As this article on making Java applications feel native shows, it's the same on Mac OS.
Your best bet is to use the techniques described in the above article to make a JNI which does the Windows API call, or get a license for JNIWrapper (search for it) which does it all for you (best option if you are making a commercial app, or making it for a client who is willing to pay for such a feature). It looks like you can get a 30-day trial for that.
The only other thing I could suggest is create a poor-man's equivalent of a pop-up notification system. When you want to alert the user, create a Frame without a border, put it in the bottom-right corner of the screen, make it non-focusable and show it for a brief period of time.
The JPanel does not flash. Try it instead of JFrame.
I have a simple Java Swing GUI Form with a browse button. The browse button creates a new JFileChooser when it's clicked.
However, if you click browse immediately after the window opens, the file chooser window seems to loose focus, showing the parent window behind it, but it refuses to repaint itself. I have to drag it off screen and back on again to get it to return to normal.
I've tried to reduce my code to the simplest version that still has the problem. (It just makes a very large browse button.
public class FormTest extends JFrame
{
private final int width = 490;
private final int height = 400;
private JPanel outerPanel;
private static FormTest myTest;
public static void main(String[] args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch( Exception e )
{
e.printStackTrace();
}
myTest = new FormTest();
myTest.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
myTest.setResizable(false);
myTest.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
closeWindow();
}
});
myTest.setVisible(true);
}
public FormTest()
{
super("Convert Ratings");
this.setSize(width, height);
initComponents();
}
private void initComponents()
{
outerPanel = new JPanel();
outerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
outerPanel.setLayout(new BoxLayout(outerPanel, BoxLayout.Y_AXIS));
outerPanel.add(Box.createRigidArea(new Dimension(0, 5)));
JButton myButton = new JButton("browse");
myButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JFileChooser fileChooser = new JFileChooser();
fileChooser.showOpenDialog(myTest);
}
});
outerPanel.add(myButton);
this.add(outerPanel);
}
private static void closeWindow()
{
int result = JOptionPane.showConfirmDialog(myTest, "Are you sure you want to close the application?",
"Question", JOptionPane.YES_NO_OPTION);
if( result == JOptionPane.YES_OPTION )
{
System.exit(0);
}
}
}
In this example, the browse button must be clicked immediately after the window opens and the bug will show itself after about 10 seconds.
Any help or suggestions would be much appreciated.
Thanks,
B.J.
Since your question has changed I'll add another answer. It looks like you're looking to use a CardLayout.
The unresponsiveness of your application is probably caused by some incorrect logic with repainting/hiding/unhiding panels.
Here is Oracle's tutorial on using it
http://download.oracle.com/javase/tutorial/uiswing/layout/card.html
New Addition:
I'm currently on a mac and I can't see the issue, I'll try it again when I'm at a PC later today.
Original Post:
Sounds like a event dispatch thread issue. Make sure you are doing anything that manipulates the GUI in the event dispatch thread.
http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html
Any long running task should use another thread or swing worker to perform it's function, otherwise it will cause things to stop responding/lock up/etc.