EDIT: Everything displays correctly when either field or hunterField hold no objects in any location. field and hunterField both exclusively hold objects which extend the same class, so I guess it may have something to do with inheritance...?
I have created a simple Agent-Based Model using MASON. The back-end works find, but when I try displaying my agents only "wall" agents are displayed. (Wall Portrayal) My code is below... Any idea?
package sim.app.celai;
import java.awt.Color;
import javax.swing.JFrame;
import sim.app.tutorial3.Tutorial3WithUI;
import sim.display.Controller;
import sim.display.Display2D;
import sim.display.GUIState;
import sim.portrayal.grid.SparseGridPortrayal2D;
import sim.util.Bag;
public class FieldWithGUI extends GUIState {
public Display2D display;
public JFrame frame;
SparseGridPortrayal2D hunterPortrayal = new SparseGridPortrayal2D();
SparseGridPortrayal2D wallPortrayal = new SparseGridPortrayal2D();
SparseGridPortrayal2D childPortrayal = new SparseGridPortrayal2D();
public FieldWithGUI() {
super(new Field(System.currentTimeMillis()));
}
public void setupPortrayals() {
childPortrayal.setField(((Field) state).field);
hunterPortrayal.setField(((Field) state).hunterField);
wallPortrayal.setField(((Field) state).wallField);
childPortrayal.setPortrayalForAll(new sim.portrayal.simple.OvalPortrayal2D(Color.blue));
hunterPortrayal.setPortrayalForAll(new sim.portrayal.simple.OvalPortrayal2D(Color.red));
wallPortrayal.setPortrayalForAll(new sim.portrayal.simple.OvalPortrayal2D(Color.green));
display.reset();
display.repaint();
}
public void quit()
{
super.quit();
if (frame!=null) frame.dispose();
frame = null; // let gc
display = null; // let gc
}
public static void main(String[] args)
{
new FieldWithGUI().createController();
}
public void start()
{
super.start();
// set up our portrayals
setupPortrayals();
}
public void init(Controller c)
{
super.init(c);
// Make the Display2D. We'll have it display stuff later.
display = new Display2D(400,400,this); // at 400x400, we've got 4x4 per array position
frame = display.createFrame();
c.registerFrame(frame); // register the frame so it appears in the "Display" list
frame.setVisible(true);
// specify the backdrop color -- what gets painted behind the displays
display.setBackdrop(Color.black);
// attach the portrayals
display.attach(childPortrayal, "children");
display.attach(hunterPortrayal, "hunter");
display.attach(wallPortrayal, "wall");
}
}
Related
package gameprojekt;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
//The GameWindow class holds the window
public class Game extends JFrame {
/*Global variable declaration*/
private int width;
private int height;
private int windowXPos;
private int windowYPos;
public static String p1 = "Player1";
public static String p2 = "Player2";
public static int playerScore = 0;
public static int oponentScore = 0;
public static int player1X;
public static int Player1Y;
public static int player2X;
public static int Player2Y;
private static boolean running = true;
public static int status = 0;
public static JFrame frame = new JFrame("Pong");
//public TestDrawPanel testPanel = new TestDrawPanel();
public static int getStatus() {
return status;
}
public static void setStatus(int status) {
Game.status = status;
}
// ------------------------------------------------------------
/**
* Creates a new JFrame window with the given size and
* center it based on the screen resolution
*/
public static final long serialVersionUID = 1L;
public Game() {
/*Local variable declaration*/
//JFrame frame = new JFrame("Pong");
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
width = (int)dim.getWidth();
height = (int)dim.getHeight();
windowXPos = width / 2 - (width / 2) / 2;
windowYPos = height / 2 - (height / 2) / 2;
// ------------------------------------------------------------
// Set size, half of the screen resolution
frame.setSize(width/2, height/2);
// Allign the window to the users resolution
frame.setLocation(windowXPos, windowYPos);
frame.setVisible(true);
frame.setResizable(false);
// By exiting the window using "X" all relevant data is closed
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
/* zum Testen auskommentiert
#Override
public void paint(Graphics g) {
System.out.println("test");
this.drawPlayer(g);
}*/
/**
* Draw the Player on the given location and with the given size
* #param g Graphics object
*/
public void drawPlayer(Graphics g) {
}
private static void gameLoop() {
Menue m = new Menue();
m.loadMenue(frame);
while (running) {
if (m.isStartPressed()) {
System.out.println("test");
}
}
}
/**
* Create the game and initialize the gameplay
*/
public static void main(String[] args) {
/*Variable declaration*/
// ------------------------------------------------------------
Game game = new Game();
game.gameLoop();
}
}
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package gameprojekt;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
*
*/
public class Menue {
/* Global variable declaration */
private int widthMenue;
private int heightMenue;
private String start = "Start";
private String highscores = "Highscores";
private boolean startPressed = false;
public JButton bStart = new JButton(start);
public JButton bScore = new JButton(highscores);
// ----------------------------------------------------
public boolean isStartPressed() {
return startPressed;
}
public void setStartPressed(boolean startPressed) {
this.startPressed = startPressed;
}
public int getWidthMenue() {
return widthMenue;
}
public void setwidthMenue(int widthMenue) {
this.widthMenue = widthMenue;
}
public int getheightMenue() {
return heightMenue;
}
public void setheightMenue(int heightMenue) {
this.heightMenue = heightMenue;
}
public void loadMenue(JFrame j) {
JPanel menue = new JPanel();
LayoutManager border = new BorderLayout();
menue.setLayout(border);
menue.setBackground(Color.black);
bStart.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setStartPressed(true);
}
});
menue.add(bStart, BorderLayout.LINE_START);
menue.add(bScore, BorderLayout.LINE_END);
j.getContentPane().add(menue);
}
}
Hi I'm having a problem that the variable startPressed seems to be getting ignored. If the button start is pressed the variable startPressed is set to true but the if statement in this while loop doesn't react to the new value:
while (running) {
if (m.isStartPressed()) {
System.out.println("test");
}
}
If I add System.out.println or Thread.sleep inside the loop then the if statement recognizes the value and is giving me the output.
I thought maybe there is a main problem in the programming structure or Java is too slow. Any ideas?
Thanks!
Your main problem is that your startPressed variable is not made volatile, and thus changing it in one thread may not be reflected in another thread. Change this and you'll see that your start button changes this variable appropriately:
private volatile boolean startPressed = false;
Your game loop shouldn't be as it flies in the face of Swing threading rules. Why not use a Swing Timer (my preference) or if you need your own roll-your own loop, then doing so in a background thread. Also consider making startPressed a "bound" variable, one that when changed tells any property change listeners that its state has been changed. This would be better than constantly polling its value.
Another comment: your code overuses statics and would be much better organized if you got rid of most of your static modifiers.
When you do something like
while(running) {
...
}
it means, that this loop is executed over and over again, nothing stops it, it gets executed as fast as your PC can do it. And therefore, it tends to block everything else. So yes, your program structure is the problem. Try to execute your game-loop in a separate thread. This thread can then update your view from time to time. Maybe think about to pause this thread from time to time or to schedule it in some way, so your view is only update every second (or whatever you want).
I have 2 classes, the first class is where I am creating GUI and all of the components needed. Including the buttons. This is being done outside of the main method and in there own respective methods. I want to .addActionListener, but from another class outside of this one. I do not want to use inner classes.
Here is the classes containing Main and the Gui components and the button.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
public class PasswordGeneratorGui {
private JFrame interfaceFrame;
private JPanel interfacePanel;
private JMenuBar interfaceMenuBar;
private JMenu interfaceMenu;
private JMenuItem interfaceMenuItemFile;
private JButton interfaceButtonGenerate;
public static void main(String[] args) {
new PasswordGeneratorGui();
}
public PasswordGeneratorGui() {
createInterfacePanel();
createInterfaceFrame();
createInterfaceMenuBar();
createInterfaceMenu();
createInterfaceMenuItem();
createInterfaceButton();
PasswordGeneratorButtonHandler b = new PasswordGeneratorButtonHandler();
interfaceFrame.add(interfacePanel);
interfaceFrame.setVisible(true);
}
public void createInterfacePanel() {
interfacePanel = new JPanel();
interfacePanel.setLayout(null);
}
public void createInterfaceFrame() {
interfaceFrame = new JFrame();
interfaceFrame.setTitle("Password Generator");
interfaceFrame.setBounds(50, 50, 700, 400);
interfaceFrame.setResizable(false);
interfaceFrame.setJMenuBar(interfaceMenuBar);
}
public void createInterfaceMenuBar() {
interfaceMenuBar = new JMenuBar();
interfaceMenuBar.setBounds(0, 0, 700, 20);
interfaceMenuBar.setVisible(true);
interfacePanel.add(interfaceMenuBar);
}
public void createInterfaceMenu() {
interfaceMenu = new JMenu("File");
interfaceMenuBar.add(interfaceMenu);
}
public void createInterfaceMenuItem() {
interfaceMenuItemFile = new JMenuItem("Exit");
interfaceMenu.add(interfaceMenuItemFile);
}
**public void createInterfaceButton() {
interfaceButtonGenerate = new JButton("Generate");
interfaceButtonGenerate.setBounds(0, 358, 700, 20);
interfaceButtonGenerate.addActionListener();
interfacePanel.add(interfaceButtonGenerate);
}**
}
Here is the class for the ActionListener
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PasswordGeneratorButtonHandler implements ActionListener {
PasswordGeneratorButtonHandler generate = new PasswordGeneratorButtonHandler();
public PasswordGeneratorButtonHandler() {
}
public void interfaceButtonGenerateHandler(ActionEvent event) {
System.exit(1);
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
I just want to be able to call the AcitonListener method from the second class. I have tried initiating a new instance of the class and calling it however I think I wasn't quite going in the correct direction.
I'm a little confused about what your asking. You said
I just want to be able to call the AcitonListener method from the second class
Taken literally this means that while you're inside of the PasswordGeneratorButtonHandler class, you want to call the actionPerformed() method. If so, just use this.actionPerformed(), where this is a special keyword in java, representing the current instance of your class.
If however you want to add your handler to the button you created in the first class, which seems like what you might want to do, then you just need to call the JButton#addActionListener() method.
public PasswordGeneratorGui() {
createInterfacePanel();
createInterfaceFrame();
createInterfaceMenuBar();
createInterfaceMenu();
createInterfaceMenuItem();
createInterfaceButton();
PasswordGeneratorButtonHandler b = new PasswordGeneratorButtonHandler();
interfaceButtonGenerate.addActionListener(b); // Add handler to button
interfaceFrame.add(interfacePanel);
interfaceFrame.setVisible(true);
}
Also, inside of the PasswordGeneratorButtonHandler class, you instantiate an instance of the class called generate. This is unnecessary.
I've got a slight problem, I'm writing a gps tracking app to track several objects at once. The data comes in over a serial interface, this is coming in fine from what I can tell. The issue is that I need to continually update the JPanel where the map is created and displayed.
public JPanel mapDisplay(){
JPanel mapPanel = new JPanel();
mapPanel.setSize(560, 540);
Coordinate start = new Coordinate (-34.9286, 138.6);
trackMap.addMapMarker(new MapMarkerDot(1Lat, 1Lon));
trackMap.setDisplayPosition(start,8);
System.out.println(1Lat);
mapPanel.add(trackMap);
mapPanel.setVisible(true);
return mapPanel;
}
This is what I have and it's happy to display the point once but won't update. If I print out the 1Lat variable in the serial method it continually prints, however it only does it once here.
A lot of the answers I've found refer to setting markers by arrays, however that won't work in this case as the objects I'm tracking could be anywhere.
Any help would be greatly appreciated :)
Is it possible to use a worker thread and not use an ArrayList? I would run the risk of missing data if I do.
Not necessarily. In a SwingWorker, your implementation of the doInBackground() method can publish() results as they become available. Note in particular that "Results from multiple invocations of publish() are often accumulated for a single invocation of process()." In your process(), simply loop through the List<Coordinate>, update the route and repaint() the map.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import org.openstreetmap.gui.jmapviewer.Coordinate;
import org.openstreetmap.gui.jmapviewer.JMapViewer;
import org.openstreetmap.gui.jmapviewer.MapPolygonImpl;
/**
* #see http://stackoverflow.com/a/37193636/230513
*/
public class MapWorkerTest {
private final List<Coordinate> route = new ArrayList<>();
private void display() {
JFrame f = new JFrame("MapWorker");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMapViewer map = new JMapViewer() {
#Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
#Override
public String getToolTipText(MouseEvent e) {
Coordinate c = (Coordinate) getPosition(e.getX(), e.getY());
return c.getLat() + " " + c.getLon();
}
};
map.setToolTipText("");
Coordinate start = new Coordinate(-34.9286, 138.6);
route.add(start);
MapPolygonImpl poly = new MapPolygonImpl(route);
poly.setColor(Color.blue);
map.addMapPolygon(poly);
map.setDisplayPosition(start, 10);
f.add(map);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
new MapWorker(map, start).execute();
}
private class MapWorker extends SwingWorker<Void, Coordinate> {
private final JMapViewer map;
private Coordinate last;
public MapWorker(JMapViewer map, Coordinate start) {
this.map = map;
this.last = start;
}
#Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
last = new Coordinate(last.getLat() + 0.0025, last.getLon() + 0.01);
publish(last);
Thread.sleep(1000);
}
return null;
}
#Override
protected void process(List<Coordinate> chunks) {
for (Coordinate c : chunks) {
route.add(c);
}
map.repaint();
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new MapWorkerTest()::display);
}
}
Multiple route management left as a exercise.
Here is what I'm trying to do - making long story short:
Building a window (will call him MainWindow) with buttons at top and a picture on the center of it. I want to give the user the options to chose what to do (the buttons) while changing the center picture every couple of sec. Part of the options given to the user is 'pause' and 'resume' - controlling the sequence.
Basically trying to update GUI (MainWindow) by a Thread. This Thread will RUN WHILE boolean 'playSequence' will be true.
Can someone explain why can't I get it to work..
Here is the Code:
package SpecializedControls;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import DataEntities.SgiImage;
public class SgiImagePanel extends JPanel implements Runnable {
private List<SgiImage> seqImageList;
private JLabel lastImage;
private boolean playSequence;
public SgiImagePanel (){}
public SgiImagePanel (List<SgiImage> sequenceList)
{
seqImageList = sequenceList ;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(playSequence)
{
for (SgiImage image : seqImageList)
{
display(image);
try {
Thread.sleep(3000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void display(SgiImage image)
{
reset();
JLabel picLabel = new JLabel(new ImageIcon(image.getImage()));
add(picLabel);
lastImage = picLabel;
}
public void display(List<SgiImage> sequenceList)
{
if(sequenceList==null)
return;
playSequence = true;
SgiImagePanel seq = new SgiImagePanel(sequenceList);
Thread thread = new Thread(seq);
thread.start();
}
public void reset(){
if (lastImage != null)
{
remove(lastImage);
lastImage = null;
}
}
public void pause() {
playSequence = false;
}
public void resume(){
playSequence = true;
}
}
Don't directly use Threads for this. There's no need, and it carries risk if you call code in a background thread that changes Swing state without care.
Use a Swing Timer for your animation loop.
Display your images as ImageIcons in a JLabel.
One of the main problems with your code is that you keep creating a bunch of new JLabels needlessly and dangerously. One JLabel is all you need and all you want. So instead, create the image displaying JLabel just once and then swap icons via its setIcon(...) method.
Read in your image Icon just once, and save it in a variable or collection.
You can easily pause a Swing Timer by simply calling its stop() method, and can restart it just as easily by calling start().
Try to load the image with this code:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class ImagePanel extends JPanel{
private BufferedImage image;
public ImagePanel() {
try {
image = ImageIO.read(new File("image name and path"));
} catch (IOException ex) {
// handle exception...
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null); // see javadoc for more info on the parameters
}
}
Hi everyone im having problems in my Blackberry application.................
I have made a simple application it starts with a file called AppStarter
package in.EventTimer;
import net.rim.device.api.ui.UiApplication;
public class AppStarter extends UiApplication
{
public static void main (String[] args)
{
AppStarter theApp = new AppStarter ();
theApp.enterEventDispatcher ();
}
public AppStarter()
{
//display a new screen
pushScreen (new ConnectionSettings ());
}
}
From this AppStarter file it pushes to the second file which is a Screen for the ConnectionSettings
package in.EventTimer;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.MainScreen;
public class ConnectionSettings extends MainScreen
{
public void RadioButton()
{
RadioButtonGroup rbg = new RadioButtonGroup();
RadioButtonField rb1 = new RadioButtonField("tcp");
RadioButtonField rb2 = new RadioButtonField("gprs");
RadioButtonField rb3 = new RadioButtonField("wifi");
rbg.add(rb1);
rbg.add(rb2);
rbg.add(rb3);
}
public boolean onClose()
{
Dialog.alert ("Exit Connection Settings!");
System.exit (0);
return true;
}
}
But when iam running this application in my Blackberry 9700 simulator it is just giving the blank white screen and when im exiting that white screen it is giving the message exitconnection settings which means it is on the connection settings screen but when i run it is showing blank white screen........i have tried many things but no solution yet ............so plz help or suggest something.
Thanks in advance
Try adding the following method to the ConnectionSettings class:
public ConnectionSettings()
{
super();
LabelField title = new LabelField("HelloWorld Sample",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
add(new RichTextField("Hello World!"));
}
Looks like you are missing a constructor... For your MainScreen class
So the final code should look like this:
package in.EventTimer;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.MainScreen;
public class ConnectionSettings extends MainScreen {
public void RadioButton()
{
RadioButtonGroup rbg = new RadioButtonGroup();
RadioButtonField rb1 = new RadioButtonField("tcp");
RadioButtonField rb2 = new RadioButtonField("gprs");
RadioButtonField rb3 = new RadioButtonField("wifi");
rbg.add(rb1);
rbg.add(rb2);
rbg.add(rb3);
add(rb1); //Added by eSniff
add(rb2); //Added by eSniff
add(rb3); //Added by eSniff
}
//Begin added by eSniff
public ConnectionSettings()
{
super();
LabelField title = new LabelField("APP STARTER",
LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
setTitle(title);
add(new RichTextField("Hello World!"));
RadioButton();
}
//End added by eSniff
public boolean onClose()
{
Dialog.alert ("Exit Connection Settings!");
System.exit (0);
return true;
}
}
Make the variable "rgb" into a class field
Define a constructor.
In that constructor, you must first call the function RadioButtons(), then call add(rgb) in your constructor, you must first call RadioButtons(), then invoke add(rgb) to ensure that your fields show up on screen.