Hot questions for Using Applets in user interface

Top Java Programmings / Applets / user interface

Question:

So I'm making a game and I want to switch it from an applet to a JFrame, as all my other classes use JFrames. However, I keep getting a bunch of run-time errors that I do not understand whatsoever.

I've mostly tried just replacing where it says extends Applet to 'extends JFrame', as well as making another class where it makes a JFrame that contains everything about the game, such as the background, movement, literally the whole game.

This is one of the classes, the one in which I declare a JFrame that contains the rest of the game:

public class SpaceGame{
     JFrame frame = new JFrame("Space Shooter");
     AlienAttack alienAttack = new AlienAttack();
     public SpaceGame(){
          frame.setBounds(320, 25, 1000, 650);
          frame.setResizable(false);
          frame.setVisible(true);
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.add(alienAttack);
     }
}

Here's the AlienAttack class that you see above:

public class AlienAttack extends JFrame implements KeyListener, Runnable
{
  double xVel; double yVel; final double SPEED = 0.02;
  Thread thread;
  int direction;
  double x, y;
  final double FRICTION = 0.98;
  boolean upAccel, downAccel, leftAccel, rightAccel;
  ArrayList<Shot> shots;
  ArrayList<Alien> aliens;
  boolean shipActive;

  public void init(){
    x=475;
    y=300;
    direction = 1;
    xVel = 0; yVel = 0;
    shipActive = true;
    upAccel = false; downAccel = false; leftAccel = false; rightAccel = false;
    shots = new ArrayList<Shot>();
    aliens = new ArrayList<Alien>();
    this.addKeyListener(this);
    thread = new Thread(this);
    thread.start();
  }

There's more to it, but that's the stuff that I think is relevant. BTW, Shot and Alien are other classes, I use those in the ArrayLists.

Some of the errors I get are:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: adding a window to a container

(That's the main one)

t java.awt.Container.checkNotAWindow(Unknown Source)
    at java.awt.Container.addImpl(Unknown Source)
    at java.awt.Container.add(Unknown Source)
    at javax.swing.JFrame.addImpl(Unknown Source)
    at java.awt.Container.add(Unknown Source)
    at SpaceGame.<init>(SpaceGame.java:11)
    at TestingGrounds$SnakeHandler.actionPerformed(TestingGrounds.java:82)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)

That's like half of them lol


Answer:

Simple:

JFrame frame = new JFrame("Space Shooter");

and

frame.add(alienAttack);

You simply can't just add another JFrame into your first one.

Thing is: any GUI framework comes with a lot of complexity. As a consequence: programming by trial and error isn't a reasonable strategy.

Therefore the real answer is: step back. You shouldn't do thing because you assume you can do that. You have to spend the hours it requires to understand what your are doing.

In your case: research swing. The Oracle tutorials are a good starting point. Simply spoken: read them, top to bottom. Read the example code, copy it, and make experiments based on that working code. Then, when you are proficient enough with Swing to "walk on your on legs", then come back and look at the structure of your current applet-based application. Apply the things you learned, and dissect what you have into those pieces that you can then re-use within a Swing application.

Depending on context, this might be rather easy, such as: deciding what your "main" frame (window) should be, to then figure out how to add the other things. I would guess that a first attempt would be about changing your AlienAttack from being a JFrame to be a JPanel. You add panels to a frame, not frames!

Question:

I am working on a knight's tour problem with basic gui,i want to take user input in the two text fields which make up the (x,y) from user and then in one text box i print if solution is posiible and in the other i write the path adopted by the knight.My algorithm works fine and i have problem in gui.i have given a few default values to (x,y) for that i get correct output .But when i change the value of (x,y) in the textfield,no change occurs.this is the main file ,there is another event handler file,which is below it.Your help will be sincerely appreciated.I am working on processing 2.2.1.This is how the output screen looks like

Main file/project.pde

// Need G4P library
import g4p_controls.*;
Maxim maxim;
AudioPlayer player;
int x=-1;
int y=-1;
String solution="";
PImage img;
int count=0;

public void setup(){
  size(480, 320, JAVA2D);
  maxim=new Maxim(this);
  player=maxim.loadFile("song.wav");
  player.setLooping(true);

  img=loadImage("chess.jpg");

  createGUI();
  customGUI();

  // Place your setup code here

}
int t[]=new int[25];
boolean visited[][]=new boolean[5][5];
int check[][]=new int[5][5];
boolean b;
int counter=-1;
boolean move(int x,int y , int m){
 boolean result=false; 
   if (x<0 || x>=5 || y<0 || y>=5 || visited[x][y]==true)
   {
        return false;
   }

    visited[x][y]=true;

    if (m==24)
    {

        visited[x][y]=true;

        return true;
    }
    else
    {
      String xstring=String.valueOf(x);
      String ystring=String.valueOf(y);
      solution=solution+xstring+","+ystring+"  ";
        print (x);
        print(",");
        print(y);
        check[x][y]=counter+1;
        if (move(x+2,y+1,m+1) || move(x+2,y-1,m+1)
            || move(x-2,y+1,m+1) || move(x-2,y-1,m+1)
            || move(x+1,y+1,m+1) || move(x+1,y-1,m+1)
            || move(x-1,y+1,m+1) || move(x-1,y-1,m+1)){
            print (x);
            print(",");
            print(y);
            //check[x][y]=1;
            return true;

            }


    return false;


}
}


public void draw(){
 counter=counter+1; 
   background(0,128,128);
   image(img,0,0,480,320);
   player.play();
   textarea2.setText(solution);


   String txt1 = textfield1.getText();
   x = Integer.parseInt(txt1);

   String txt2 = textfield2.getText();
   y= Integer.parseInt(txt2);
   print(solution);
   if(x>=0 && y>=0)
   {
     b=move(x,y,0);


     if(b==false)
     {
       textarea1.setText("Solution is not possible,enter other coordinates");
     }
     if(b==true)
     {
       textarea1.setText("Congratulations solution is possible");
     }
   }
   if(count%8==0)
   {
     delay(1000);
     println(counter);

   }

}
void keyPressed()
{
  if (key==13)
  {
    solution="";
    print(solution);
    textarea2.setText(solution);
    String txt1 = textfield1.getText();
   x = Integer.parseInt(txt1);

   String txt2 = textfield2.getText();
   y= Integer.parseInt(txt2);
  }
    if(x>=0 && y>=0)
   {
     b=move(x,y,0);


     if(b==false)
     {
       textarea1.setText("Solution is not possible,enter other coordinates");
     }
     if(b==true)
     {
       textarea1.setText("Congratulations solution is possible");
     }
   }
}

// Use this method to add additional statements
// to customise the GUI controls
public void customGUI(){

}

this is the event handlers file

/* =========================================================
 * ====                   WARNING                        ===
 * =========================================================
 * The code in this tab has been generated from the GUI form
 * designer and care should be taken when editing this file.
 * Only add/edit code inside the event handlers i.e. only
 * use lines between the matching comment tags. e.g.

 void myBtnEvents(GButton button) { //_CODE_:button1:12356:
     // It is safe to enter your event code here  
 } //_CODE_:button1:12356:

 * Do not rename this tab!
 * =========================================================
 */

public void tf1(GTextField source, GEvent event) { //_CODE_:textfield1:418637:
  println("textfield1 - GTextField >> GEvent." + event + " @ " + millis());
} //_CODE_:textfield1:418637:

public void tf2(GTextField source, GEvent event) { //_CODE_:textfield2:859413:
  println("textfield2 - GTextField >> GEvent." + event + " @ " + millis());
} //_CODE_:textfield2:859413:

public void ta1(GTextArea source, GEvent event) { //_CODE_:textarea1:252891:
  println("textarea1 - GTextArea >> GEvent." + event + " @ " + millis());
} //_CODE_:textarea1:252891:

public void ta2(GTextArea source, GEvent event) { //_CODE_:textarea2:483845:
  println("textarea2 - GTextArea >> GEvent." + event + " @ " + millis());
} //_CODE_:textarea2:483845:

public void slider1_change1(GSlider source, GEvent event) { //_CODE_:slider1:280049:
  println("slider1 - GSlider >> GEvent." + event + " @ " + millis());
} //_CODE_:slider1:280049:

public void slider2_change1(GSlider source, GEvent event) { //_CODE_:slider2:362722:
  println("slider2 - GSlider >> GEvent." + event + " @ " + millis());
} //_CODE_:slider2:362722:



// Create all the GUI controls. 
// autogenerated do not edit
public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setCursor(ARROW);
  if(frame != null)
    frame.setTitle("Sketch Window");
  textfield1 = new GTextField(this, 210, 32, 160, 30, G4P.SCROLLBARS_NONE);
  textfield1.setText("1");
  textfield1.setPromptText("Enter x-Cordinate");
  textfield1.setOpaque(true);
  textfield1.addEventHandler(this, "tf1");
  textfield2 = new GTextField(this, 204, 96, 160, 30, G4P.SCROLLBARS_NONE);
  textfield2.setText("1");
  textfield2.setPromptText("Enter y Cordinate");
  textfield2.setLocalColorScheme(GCScheme.PURPLE_SCHEME);
  textfield2.setOpaque(true);
  textfield2.addEventHandler(this, "tf2");
  textarea1 = new GTextArea(this, 53, 196, 160, 80, G4P.SCROLLBARS_NONE);
  textarea1.setLocalColorScheme(GCScheme.GREEN_SCHEME);
  textarea1.setOpaque(true);
  textarea1.addEventHandler(this, "ta1");
  textarea2 = new GTextArea(this, 288, 192, 160, 80, G4P.SCROLLBARS_NONE);
  textarea2.setLocalColorScheme(GCScheme.YELLOW_SCHEME);
  textarea2.setOpaque(true);
  textarea2.addEventHandler(this, "ta2");
  slider1 = new GSlider(this, 96, 276, 264, 40, 10.0);
  slider1.setLimits(0.5, 0.0, 1.0);
  slider1.setNumberFormat(G4P.DECIMAL, 2);
  slider1.setOpaque(false);
  slider1.addEventHandler(this, "slider1_change1");
  slider2 = new GSlider(this, 348, 240, 100, 36, 10.0);
  slider2.setLimits(0.5, 0.0, 1.0);
  slider2.setNumberFormat(G4P.DECIMAL, 2);
  slider2.setOpaque(false);
  slider2.addEventHandler(this, "slider2_change1");
}

// Variable declarations 
// autogenerated do not edit
GTextField textfield1; 
GTextField textfield2; 
GTextArea textarea1; 
GTextArea textarea2; 
GSlider slider1; 
GSlider slider2; 

Answer:

There are some problems with above constructions. You do recursive move() method inside draw() method. But in Processing draw() is called many times in each second by animation thread.

Common desing for such cases is:

  • you should have variables that hold application state (logical state)
  • what your draw() method draws depends only on state
  • state may be modified by animation thread or by any other thread

I suggest changing your code a little:

First - state variables:

// 1 - display status, wait to enter values
// 2 - check if x and y are correct
// 3 - solve problem
int state=1;
boolean solutionExists=false;

public void setup() {
...
}

next draw() method:

void draw() {

   counter=counter+1; 
   background(0,128,128);

   String coords = "(" + x + "," + y + ")";

  if (state == 1) {
     if(solutionExists) {
       textarea1.setText("Congratulations solution is possible  " + coords);       
     } else {
       textarea1.setText("Solution is not possible,enter other coordinates  " +coords);
     }

     return; 
  }

  if (state == 2) {
    readXY();
    return;
  }

  if (state == 3) {
    println("find solution for: " + coords);
    solutionExists = move(x,y,0);
    state = 1;
    return;
  }

}

public void readXY() {
  try {
   x = Integer.parseInt(textfield1.getText().trim());
   y = Integer.parseInt(textfield2.getText().trim());
   state = 3;
  } catch(Exception e) {
    state = 1;
  }

}

and finally textfields handlers:

public void tf1(GTextField source, GEvent event) {
  if (event.getType().equals("LOST_FOCUS")) {
    state=2;
  }
}

public void tf2(GTextField source, GEvent event) {
  if (event.getType().equals("LOST_FOCUS")) {
    state=2;
  } 
}

As you can see:

  • if state==1 - draw() only updates message
  • if state==2 - draw() checks if x and y are valid, if valid -> change state to 3
  • if state==3 - draw() performs recursive algo, update solutionExists variable, change state to 1

Anytime when your textfield1 or textfield2 loose focus, it changes state to 2.

  • draw() is driven only by application state.
  • application state is modified by other events.

For best results, recursive algo should be performat in another thread, not in animation thread.

One fine note: when you edit textfield it may contains string such as "" (empty) or " 3" (leading space) or " 3 " etc - such text cannot be parsed with Integer.parseInt - you need to trim such text and be sure that NumberFormatException is not thrown - see readXY() method.

Question:

Note: I have the correct processing.core library imported on my project already with build paths created.

import processing.core.*; 

public class MyPApplet extends PApplet{

    private String URL = "https://www.bali.com/media/image/663/best-resorts-bali.jpg"; 
    private PImage backgroundImage; 

    public void setup() {
        size(400, 400); 
        backgroundImage = loadImage(URL, "jpg"); 
    }
    public void draw() { 
        image(backgroundImage, 0, 0); 
    }
}

Answer:

The other answer is half correct, but I think I understand why you were confused.

You can run Java code without a main() function, as long as that code is an applet. The problem is that your code is not an applet, so it requires a main() function.

This is a little bit confusing, because before Processing 3, PApplet did extend the Applet class, so a Processing sketch was an applet. But after Processing 3, that's no longer the case, so you can't run a Processing sketch as an applet. If you're following an outdated tutorial, that's the source of your confusion.

Also note that if you're using Processing from Java, you should use the settings() function instead of the setup() function.

Shameless self-promotion: I've written a tutorial on using Processing as a Java library available here.

Question:

I have made a Java Applet.

<applet code=gui.clientGUI.MyApplet.class 
        archive="QTminer.jar"
        width=400 height=200>
</applet>

my jar looks like this:

this is my simple code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

public class MyApplet extends JApplet {

    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    initUI();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initUI() {
        getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

        JButton btnStartApplication = new JButton("Start Application");
        btnStartApplication.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                SS oi = new SS();
                oi.setVisible(true);
            }
        });
        getContentPane().add(btnStartApplication);
    }
}

class SS extends JWindow {

    private JLabel lblNewLabel;
    private JLabel label;

    public SS() {
    setBounds(new Rectangle(0, 0, 883, 590));
    setLocationRelativeTo(null);
    getContentPane().setLayout(null);

    lblNewLabel = new JLabel("Welcome", SwingConstants.CENTER);
    lblNewLabel.setForeground(Color.RED);
    lblNewLabel.setFont(new Font("Segoe UI", Font.BOLD | Font.ITALIC, 24));
    lblNewLabel.setBounds(0, 313, 883, 41);
    getContentPane().add(lblNewLabel);

    label = new JLabel(new ImageIcon(getClass().getResource("/gui/resources/Qtminer_background.jpg")));

    label.setBounds(0, 0, 883, 592);
    getContentPane().add(label);

    setVisible(true);
}
}

My problem is that when running in eclipse everything works, but when running in browser i get a NullPointerException right on the load of the image icon:

label.setIcon(new ImageIcon(getClass().getResource("/gui/resources/Qtminer_background.jpg")));

Answer:

My OS denied access to the local file jar.

Testing the applet on a real web-server made it work.

Solved!

Question:

recently I have discovered substance. When i try to load it in my java program (not applet!) I get errors during startup.

SwingUtilities.invokeLater(new Runnable()
{
    @Override
    public void run()
    {
        try
        {
            UIManager.setLookAndFeel(new SubstanceGraphiteAquaLookAndFeel());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
});

And those are the errors (Note: Those are pop ups, where --message-- is the title, and {name} are buttons):

  • --APPLET ALERT-- The applet is attempting to connect to jar: [...]/substance-6.0/org/pushingpixel/substance/api/skin/graphite.colorschemes. {Allow} {Disallow} {Stop Applet}
  • --APPLET ALERT-- The applet is attempting to invoke the java/lang/System.getenv() operatoin on KDE_FULL_SESSION {Allow} {Disallow} {Stop Applet}

The last message appears 5 times whilst writing the following into stderr

-->> returning Frame NULL
BaseDialog: owner frame is a java.awt.Frame

Also my first window will be loaded with the default swing ui. After closing this and opening a new one (programmatically) the ui will be initialized.

Is there any way I can bypass the error?

Edit: I use the following libraries: laf-plugin-7.2; laf-widget-7.0; substance-6.0


Answer:

I downloaded a fork from: https://github.com/Insubstantial/insubstantial/downloads

The other one was not signed because i compiled it myself.