I want to draw images but I want to show it in a frame when all the img will be draw. My current code:
public class TestURLImage3 extends JFrame {
private static ArrayList<BusStop2> list = new ArrayList<>();
private static ArrayList<PositionTilesAndURLPaths> positionTilesAndURLPathsList = new ArrayList<>();
private static ArrayList<Image> imgList = new ArrayList<>();
private static ConcurrentHashMap<String, BufferedImage> imgCache = new ConcurrentHashMap<>();
public static void main(String[] args) {
new TestURLImage3();
}
TestURLImage3(){
setUndecorated(false);
setAlwaysOnTop(true);
setSize(Config.xSize, Config.ySize);
setDefaultCloseOperation(EXIT_ON_CLOSE);
getTiles(51.407,16.198);
getImgPositionAndURLsPath(list);
setVisible(true);
setLayout(null);
}
public void paint ( Graphics g ) {
super.paint(g);
getPaint(g);
}
private static void getPaint(Graphics g){
for(PositionTilesAndURLPaths pos : getImgPositionAndURLsPath(list)){
ImageIcon icon = new ImageIcon(getImgFromPath(pos.getPath()));
Image img = icon.getImage();
g.drawImage(img,Config.xSize/2-pos.getX()-Config.imgSize/2 ,(Config.ySize/2)- pos.getY()-Config.imgSize/2, Config.imgSize, Config.imgSize, null);
}
}
/**
* Method use to get image by geographical coordinates
* #param lat
* #param lon
* #return
*/
// private String getFirstImage(double lat, double lon ){
// return new String(TestURLImage.getImg(lat, lon, Config.mapZoom));
// }
/**
* Method use to get image from path
* #param path
* #return
*/
private static BufferedImage getImgFromPath(String path){
if(imgCache.get(path) != null){
return imgCache.get(path);
}
else{
URL url = null;
BufferedImage image = null;
try {
url = new URL(path);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
image = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
imgCache.put(path, image);
return image;
}
}
/**
* Method use to get count of image what we need
* #return
*/
private static int[] getCountImage(){
int xImageCount = (int) Math.ceil(Config.xSize/256);
int yImageCount = (int) Math.ceil(Config.ySize/256);
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get count of tiles
* #return
*/
private static int[] countImage(){
int[] imageCount = getCountImage();
int xImageCount = imageCount[0];
int yImageCount = imageCount[1];
if(xImageCount-1 %2 != 0){
xImageCount = xImageCount + 2;
}
if(yImageCount-1 %2 != 0){
yImageCount = yImageCount + 2;
}
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get tiles
* #param lat
* #param lon
* #return
*/
private static ArrayList<BusStop2> getTiles(double lat, double lon ){
int [] numberTile = TestURLImage.getMapByGeographicalCoordinates(lat, lon, Config.mapZoom);
int a1 = 1;
int a2 = 1;
int a3 = 1;
int a4 = 1;
int [] countImage = countImage();
int []x = new int [countImage[0]];
int []y = new int [countImage[1]];
x[0] = numberTile[0];
y[0] = numberTile[1];
for (int i = 1; i<x.length; i++){
if(i%2==0){
x[i] = numberTile[0]+(a1);
a1++;
}
else{
x[i] = numberTile[0]-(a2);
a2++;
}
}
for (int i = 1; i<y.length; i++){
if(i%2==0){
y[i] = numberTile[1]+(a3);
a3++;
}
else{
y[i] = numberTile[1]-(a4);
a4++;
}
}
for(int i = 0 ; i<x.length ; i++){
for (int j = 0 ;j<y.length ; j++ ){
list.add(new BusStop2(x[i], y[j], x[0] - x[i], y[0]-y[j]));
}
}
return list;
}
/**
*
* #param list
* #return
*/
private static ArrayList<PositionTilesAndURLPaths> getImgPositionAndURLsPath(ArrayList<BusStop2> list){
for(BusStop2 bus : list){
positionTilesAndURLPathsList.add(new PositionTilesAndURLPaths(256*bus.getX(), 256*bus.getY(), Config.mapPath + "/" + bus.getA() + "/" + bus.getB() + ".png"));
}
return positionTilesAndURLPathsList;
}
}
I see how one img will be add and another ...
So I do it this :
public class TestURLImage2 {
int result[];
private static ArrayList<BusStop2> list = new ArrayList<>();
private static ArrayList<PositionTilesAndURLPaths> positionTilesAndURLPathsList = new ArrayList<>();
private static ConcurrentHashMap<String, BufferedImage> imgCache = new ConcurrentHashMap<>();
public static void main(String[] args) {
new TestURLImage2();
getTiles(51.407,16.198);
getImgPositionAndURLsPath(list);
}
public TestURLImage2() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
try {
JFrame f = new JFrame();
f.setSize(Config.xSize, Config.ySize);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setAlwaysOnTop(true);
f.setSize(Config.xSize, Config.ySize);
f.setVisible(true);
f.setLayout(null);
getTiles(51.407,16.198);
for(PositionTilesAndURLPaths pos : getImgPositionAndURLsPath(list)){
JLabel label = new JLabel(new ImageIcon(getImgFromPath(pos.getPath())));
label.setBounds(Config.xSize/2-pos.getX()-Config.imgSize/2 ,(Config.ySize/2)- pos.getY()-Config.imgSize/2, Config.imgSize, Config.imgSize);
f.getContentPane().add(label);
}
System.out.println(imgCache.size());
} catch (Exception exp) {
exp.printStackTrace();
}
}
});
}
/**
* Method use to get image from path
* #param path
* #return
*/
private BufferedImage getImgFromPath(String path){
if(imgCache.get(path) != null){
return imgCache.get(path);
}
else{
URL url = null;
BufferedImage image = null;
try {
url = new URL(path);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
image = ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
imgCache.put(path, image);
return image;
}
}
/**
* Method use to get count of image what we need
* #return
*/
private static int[] getCountImage(){
int xImageCount = (int) Math.ceil(Config.xSize/256);
int yImageCount = (int) Math.ceil(Config.ySize/256);
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get count of tiles
* #return
*/
private static int[] countImage(){
int[] imageCount = getCountImage();
int xImageCount = imageCount[0];
int yImageCount = imageCount[1];
if(xImageCount-1 %2 != 0){
xImageCount = xImageCount + 2;
}
if(yImageCount-1 %2 != 0){
yImageCount = yImageCount + 2;
}
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get tiles
* #param lat
* #param lon
* #return
*/
private static ArrayList<BusStop2> getTiles(double lat, double lon ){
int [] numberTile = TestURLImage.getMapByGeographicalCoordinates(lat, lon, Config.mapZoom);
int a1 = 1;
int a2 = 1;
int a3 = 1;
int a4 = 1;
int [] countImage = countImage();
int []x = new int [countImage[0]];
int []y = new int [countImage[1]];
x[0] = numberTile[0];
y[0] = numberTile[1];
for (int i = 1; i<x.length; i++){
if(i%2==0){
x[i] = numberTile[0]+(a1);
a1++;
}
else{
x[i] = numberTile[0]-(a2);
a2++;
}
}
for (int i = 1; i<y.length; i++){
if(i%2==0){enter code here
y[i] = numberTile[1]+(a3);
a3++;
}
else{
y[i] = numberTile[1]-(a4);
a4++;
}
}
for(int i = 0 ; i<x.length ; i++){
for (int j = 0 ;j<y.length ; j++ ){
list.add(new BusStop2(x[i], y[j], x[0] - x[i], y[0]-y[j]));
}
}
return list;
}
/**
*
* #param list
* #return
*/
private static ArrayList<PositionTilesAndURLPaths> getImgPositionAndURLsPath(ArrayList<BusStop2> list){
for(BusStop2 bus : list){
positionTilesAndURLPathsList.add(new PositionTilesAndURLPaths(256*bus.getX(), 256*bus.getY(), Config.mapPath + "/" + bus.getA() + "/" + bus.getB() + ".png"));
}
return positionTilesAndURLPathsList;
}
}
But I have to wait 10 seconds for the screen and it is too long. How could I speed up the process?
Related
I am working on an assignment and I'm almost done, however, there is a bullet that tells me to draw a line between the adjacent components to approximate the distance between them. I searched for the answer everywhere, and none of them worked.
Here's the code, I cut out the unimportant things, thanks in advance!
//IMPORTS
public class AssignLIRRBranches implements Runnable
{
static final String title = "LIRR Map";
static final String RK = "Ronkonkoma";
static final String MONTAUK = "Montauk";
static final String PJ = "Port_Jefferson";
static int width = 1200;
static int height = 600;
static int mapwidth = width-100;
static int mapheight = height-50;
double scalingFactorx;
double scalingFactory;
double scalingFactor;
double drawingX;
double drawingY;
double drawingY2;
MapPanel mapPanel = new MapPanel(new Font("Arial", Font.ITALIC, 12), false, Color.black, "kek", 12, 12, 12, 12);
JFrame application;
BoxLayout boxLayout;
Station station;
List<Station> stations = new ArrayList<Station>();
String[] larray;
JComboBox jbc;
public void run()
{
/* build the GUI */
application = new JFrame();
jbc = new JComboBox();
jbc.addItem(RK);
jbc.addItem(MONTAUK);
jbc.addItem(PJ);
boxLayout = new BoxLayout(application.getContentPane(), BoxLayout.Y_AXIS);
jbc.setMaximumSize(new Dimension(150, 15));
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setTitle(title);
application.setSize(width, height);
application.setLayout(boxLayout);
mapPanel.setPreferredSize(new Dimension(mapwidth, mapheight));
application.add(mapPanel);
application.add(jbc);
application.setMinimumSize(application.getSize());
application.pack();
application.setMinimumSize(null);
application.setVisible(true);
}
void readStations(String path) throws FileNotFoundException, IOException {
/* read all stations */
try{ BufferedReader br = new BufferedReader(new FileReader(path));
String l;
while((l = br.readLine()) != null) {
larray = l.split(" ");
if(larray[2].equals(RK) || larray[2].equals(MONTAUK) || larray[2].equals(PJ)) {
/* construct and save Station instances */
station = new Station(Integer.parseInt(larray[0]), larray[1], larray[2], Double.parseDouble(larray[4]), Double.parseDouble(larray[5]));
stations.add(station);
}
}
} catch(NumberFormatException exc) {
System.out.println(exc);
}
}
public static void main(String[] args) throws FileNotFoundException, IOException {
String path = "lirr_sta_alpha.txt";
AssignLIRRBranches ars = new AssignLIRRBranches();
ars.readStations(path);
SwingUtilities.invokeLater(ars);
}
class Station {
int id = 0;
String NAME = " ";
String BRANCH = " ";
double latitude;
double longitude;
Station(int id, String NAME, String BRANCH, double longitude, double latitude) {
this.longitude = longitude;
this.latitude = latitude;
this.NAME = NAME;
this.BRANCH = BRANCH;
this.id = id;
}
//GETTERS AND SETTERS
}
class MapPanel extends JPanel implements ComponentListener {
Font mapFont;
boolean resized = false;
Color mapColor = Color.black;
String currentBranch;
double minLong, minLat, maxLong, maxLat;
MapPanel(Font mapFont, boolean resized, Color mapColor, String currentBranch, double minLong, double minLat, double maxLong, double maxLat) {
/* construct the MapPanel */
this.mapFont = mapFont;
this.resized = resized;
this.mapColor = mapColor;
this.currentBranch = currentBranch;
this.minLong = minLong;
this.minLat = minLat;
this.maxLong = maxLong;
this.maxLat = maxLat;
}
void extents() {
minLong = Double.MAX_VALUE;
minLat = Double.MAX_VALUE;
maxLong = -Double.MIN_VALUE;
maxLat = -Double.MIN_VALUE;
for(Station station : stations){
/* calculate minimum and maximum longitude and latitude for staions of the current branch */
if(station.getBranch().equals(jbc.getSelectedItem())) {
if(station.getLatitude()>maxLat){
maxLat = station.getLatitude();
maxLong = station.getLongitude();
}
if(station.getLatitude()<minLat){
minLat = station.getLatitude();
minLong = station.getLongitude();
}
}
}
}
public void paint(Graphics gr) {
Graphics2D g2 = (Graphics2D)gr;
if (null == mapFont) {
}
/* get the desired font and calulate margin values */
else
/* set the current font */
if (resized) {
/* rescale, taking into account margins */
}
/* set the color */
gr.setColor(mapColor);
/* iterate through the stations */
for (int i = 0; i < stations.size(); i++) {
if(stations.get(i).getBranch().equals(jbc.getSelectedItem())) {
//System.out.println(jbc.getSelectedItem());
/* calculate the corrdinates and draw the station name */
extents();
scalingFactorx = mapwidth/(maxLat - minLat);
scalingFactory = mapheight/(maxLong - minLong);
scalingFactor = Math.min(scalingFactorx, scalingFactory);
drawingX = (stations.get(i).getLatitude() - minLat) * scalingFactorx/1.1;
drawingY = (stations.get(i).getLongitude() - minLong) * scalingFactory/1.1;
drawingY2 = mapheight - drawingY;
gr.drawString(stations.get(i).getName(), (int)drawingX, (int)drawingY2-25);
//THIS IS WHERE I WANT TO DRAW A LINE
//gr.drawLine(I already tried using a ListIterator, it didn't work, tried getting the next element and it's values, didn't work, what can I do?);
}
}
mapPanel.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
mapwidth = application.getWidth()-150;
mapheight = application.getHeight()-75;
application.repaint();
}
});
jbc.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
application.repaint();
}
});
}
}
}
So, I am currently making a program in java, but I would like to make the program so that it changes the file output name corresponding to an integer in my class:
if(height > 10){
And here is my whole code
import java.awt.*;
public class imageReader {
private BufferedImage img, imageOut;
private int imageHeight, imageWidth;
private int deepbkg;
public imageReader() {
initializeSet();
readImage();
ProcessImage();
createOutImage();
saveProcFile();
}
public static void main(String[] args) {
#SuppressWarnings("unused")
imageReader iR= new imageReader();
}
public void initializeSet() {
Color cold = new Color(250, 100, 200);
deepbkg = cold.getRGB();
}
public void readImage(){
try{
img = ImageIO.read(new File("C:\\Users\\David_tmp\\Desktop\\ProjectImages\\LongIslandforPrint.jpg"));
}
catch (IOException e) {
}
}
public void ProcessImage(){
imageHeight = img.getHeight();
imageWidth = img.getWidth();
System.out.println(imageHeight+ " "+imageWidth );
}
public void createOutImage(){
imageOut = new BufferedImage(imageWidth, imageHeight, 1);
for (int imageX = 0; imageX < imageWidth; imageX++) {
for (int imageY = 0; imageY < imageHeight; imageY++){
int redbluevalue = img.getRGB(imageX, imageY);
double height = getHeight(redbluevalue);
// *****IMAGE HEIGHT****
if(height > 10){
//***END OF HEIGHT****
imageOut.setRGB(imageX, imageY, redbluevalue);
}
else{
imageOut.setRGB(imageX, imageY, deepbkg);
}
}
}
}
public void saveProcFile() {
try {
File outputfile = new File("C:\\Users\\David_tmp\\Desktop\\ProjectImages\\LongIslandforrrrPrint.jpg");
ImageIO.write(imageOut, "jpg", outputfile);
}
catch(IOException e) {
}
}
public double getHeight(int RGB) {
double heightX =0.;
Color tcol = new Color(RGB);
int Red = tcol.getRed();
int Blue = tcol.getBlue();
int Green = tcol.getGreen();
if( Red >248) {
heightX = 81.+ 99 * ((double)Red/250.);
}
if( Red <= 7 ) {
if(Green >= 249 ) // using blue value to calculate height
// range 23 -81
{
heightX = 23. + 58. *((double)255 - Blue)/255.;
}
else //using green to calculate height
{
heightX = 24.* ((double)Green-20.)/230.;
}
}
return heightX;
}
}
so I would like
LongIslandforrrrPrint.jpg
To change on the integer here:
if(height > 10){
So the file output would change corresponding to the integer
so the file name output would be like this
Heightmap[Integer].jpg
Something like this?
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class imageReader {
private BufferedImage img, imageOut;
private int imageHeight, imageWidth;
private int deepbkg;
public imageReader() {
initializeSet();
readImage();
ProcessImage();
createOutImage();
saveProcFile();
}
public static void main(String[] args) {
#SuppressWarnings("unused")
imageReader iR= new imageReader();
}
public void initializeSet() {
Color cold = new Color(250, 100, 200);
deepbkg = cold.getRGB();
}
public void readImage(){
try{
img =
ImageIO.read(new File("C:\\Users\\David_tmp\\Desktop\\ProjectImages\\LongIslandforPrint.jpg"));
}
catch (IOException e) {
}
}
public void ProcessImage(){
imageHeight = img.getHeight();
imageWidth = img.getWidth();
System.out.println(imageHeight+ " "+imageWidth );
}
public double myNum = 0;
public void createOutImage(){
imageOut = new BufferedImage(imageWidth, imageHeight, 1);
for (int imageX = 0; imageX < imageWidth; imageX++) {
for (int imageY = 0; imageY < imageHeight; imageY++){
int redbluevalue = img.getRGB(imageX, imageY);
double height = getHeight(redbluevalue);
// *****IMAGE HEIGHT****
if(height > 10){
//***END OF HEIGHT****
myNum = height;
imageOut.setRGB(imageX, imageY, redbluevalue);
}
else{
myNum = height;
imageOut.setRGB(imageX, imageY, deepbkg);
}
}
}
}
public void saveProcFile(){
try{
File outputfile = new File("C:\\Users\\David_tmp\\Desktop\\ProjectImages\\Heightmap["+ myNum + "].jpg");
ImageIO.write(imageOut, "jpg", outputfile);
}
catch(IOException e) {
}
}
public double getHeight(int RGB){
double heightX =0.;
Color tcol = new Color(RGB);
int Red = tcol.getRed();
int Blue = tcol.getBlue();
int Green = tcol.getGreen();
if( Red >248) {
heightX = 81.+ 99 * ((double)Red/250.);
}
if( Red <= 7 ){
if(Green >= 249 ) // using blue value to calculate height
// range 23 -81
{
heightX = 23. + 58. *((double)255 - Blue)/255.;
}
else //using green to calculate height
{
heightX = 24.* ((double)Green-20.)/230.;
}
}
return heightX;
}
}
I have on 3 class , 3 stage and I want to do something like this: that I want to do show stage . One time I show 1st stage for 10 sec, next I show 2nd stage for 10 sec and next I show 3rd stage for 10 sec and next I show 1st .... But very important is this that the 3 stage have to work all time .
In swing I will be use CardLayout but here I don't know how do this.
code for one class:
public class SimpleSlideShowTest extends Application{
class SimpleSlideShow {
StackPane root = new StackPane();
ImageView[] slides;
public SimpleSlideShow() {
this.slides = new ImageView[4];
File file1 = new File("C:/Users/022/workspace22/EkranLCD/res/images/belka.png");
Image image1 = new Image(file1.toURI().toString());
File file = new File("C:/Users/022/workspace22/EkranLCD/res/images/kropka.png");
Image image2 = new Image(file.toURI().toString());
Image image3 = new Image(file1.toURI().toString());
Image image4 = new Image(file1.toURI().toString());
slides[0] = new ImageView(image1);
slides[1] = new ImageView(image2);
slides[2] = new ImageView(image3);
slides[3] = new ImageView(image4);
}
public StackPane getRoot() {
return root;
}
// The method I am running in my class
public void start() {
SequentialTransition slideshow = new SequentialTransition();
for (ImageView slide : slides) {
SequentialTransition sequentialTransition = new SequentialTransition();
FadeTransition fadeIn = getFadeTransition(slide, 0.0, 1.0, 0);
PauseTransition stayOn = new PauseTransition(Duration.millis(2000));
FadeTransition fadeOut = getFadeTransition(slide, 0, 0.0, 2000);
sequentialTransition.getChildren().addAll(fadeIn, stayOn, fadeOut);
slide.setOpacity(0);
this.root.getChildren().add(slide);
slideshow.getChildren().add(sequentialTransition);
}
slideshow.play();
}
// the method in the Transition helper class:
public FadeTransition getFadeTransition(ImageView imageView, double fromValue, double toValue, int durationInMilliseconds) {
FadeTransition ft = new FadeTransition(Duration.millis(durationInMilliseconds), imageView);
ft.setFromValue(fromValue);
ft.setToValue(toValue);
return ft;
}
}
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
SimpleSlideShow simpleSlideShow = new SimpleSlideShow();
Text msg = new Text("java2s.com d sad adas dsa sad dsa dsa dsa dsa sdasa dsa dsa");
msg.setFont(Font.font ("Verdana", 40));
msg.setY(Config.ySize-(Config.ySize/6));
Pane root1 = new Pane(msg);
root1.setLayoutX(Config.xSize/2);
root1.setLayoutY(Config.ySize-(Config.ySize/5));
root1.setPrefSize(Config.xSize/2,400);
Main2.start(msg);
simpleSlideShow.getRoot().getChildren().add(root1);
Scene scene = new Scene(simpleSlideShow.getRoot());
primaryStage.setScene(scene);
primaryStage.show();
simpleSlideShow.start();
}
}
My second class which I want to add
public class TestURLImage4 extends Application {
public static ArrayList<BusStop2> list = new ArrayList<>();
public static ArrayList<PositionTilesAndURLPaths> positionTilesAndURLPathsList = new ArrayList<>();
public static HashMap<String, Image> imgCache = new HashMap<>();
public static double lat;
public static double lon;
public static double deltaY;
public static double deltaX;
public static double positionX;
public static double positionY;
public static int[] imageCount = getCountImage();
public static int [] countImage = countImage();
public static int []x = new int [countImage[0]];
public static int []y = new int [countImage[1]];
private File file = new File("C:/Users/ElteGps 022/workspace22/EkranLCD/res/images/kropka.png");
private Image bus = new Image(file.toURI().toString());
public TestURLImage4() {
}
TestURLImage4(double lat, double lon){
int [] tiles= getTileNumber(lat, lon, Config.mapZoom);
deltaX = tile2lon(tiles[0] + 1 , Config.mapZoom) - tile2lon(tiles[0], Config.mapZoom);
deltaY = tile2lat(tiles[1], Config.mapZoom) - tile2lat(tiles[1] + 1 , Config.mapZoom);
positionX = (lon - tile2lon(tiles[0], Config.mapZoom)) * Config.imgSize/deltaX;
positionY = (tile2lat(tiles[1], Config.mapZoom) - lat) * Config.imgSize/deltaY;
getTiles(lat,lon);
getImgPositionAndURLsPath(list);
}
/**
* Method use to get count of image what we need
* #return
*/
private static int[] getCountImage(){
int xImageCount = (int) Math.ceil(Config.xSize/256);
int yImageCount = (int) Math.ceil(Config.ySize/256);
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get count of tiles
* #return
*/
public static int[] countImage(){
int xImageCount = imageCount[0];
int yImageCount = imageCount[1];
if(xImageCount-1 %2 != 0){
xImageCount = xImageCount + 2;
}
if(yImageCount-1 %2 != 0){
yImageCount = yImageCount + 2;
}
return new int[] {xImageCount, yImageCount};
}
/**
* Method use to get tiles
* #param lat
* #param lon
* #return
*/
private static ArrayList<BusStop2> getTiles(double lat, double lon ){
int [] numberTile = getTileNumber(lat, lon, Config.mapZoom);
int a1 = 1;
int a2 = 1;
int a3 = 1;
int a4 = 1;
x[0] = numberTile[0];
y[0] = numberTile[1];
for (int i = 1; i<x.length; i++){
if(i%2==0){
x[i] = numberTile[0]+(a1);
a1++;
}
else{
x[i] = numberTile[0]-(a2);
a2++;
}
}
for (int i = 1; i<y.length; i++){
if(i%2==0){
y[i] = numberTile[1]+(a3);
a3++;
}
else{
y[i] = numberTile[1]-(a4);
a4++;
}
}
for(int i = 0 ; i<x.length ; i++){
for (int j = 0 ;j<y.length ; j++ ){
list.add(new BusStop2(x[i], y[j], x[0] - x[i], y[0]-y[j]));
}
}
return list;
}
/**
*
* #param list
* #return
*/
private static ArrayList<PositionTilesAndURLPaths> getImgPositionAndURLsPath(ArrayList<BusStop2> list){
for(BusStop2 bus : list){
positionTilesAndURLPathsList.add(new PositionTilesAndURLPaths(256*bus.getX(), 256*bus.getY(),
Config.mapPath + "/" + bus.getA() + "/" + bus.getB() + ".png"));
}
return positionTilesAndURLPathsList;
}
public static int [] getTileNumber(final double lat, final double lon, final int zoom) {
int xtile = (int)Math.floor( (lon + 180) / 360 * (1<<zoom) ) ;
int ytile = (int)Math.floor( (1 - Math.log(Math.tan(Math.toRadians(lat)) + 1 / Math.cos(Math.toRadians(lat))) / Math.PI) / 2 * (1<<zoom) ) ;
if (xtile < 0)
xtile=0;
if (xtile >= (1<<zoom))
xtile=((1<<zoom)-1);
if (ytile < 0)
ytile=0;
if (ytile >= (1<<zoom))
ytile=((1<<zoom)-1);
return new int[] {xtile, ytile};
}
static double tile2lon(int x, int z) {
return x / Math.pow(2.0, z) * 360.0 - 180;
}
static double tile2lat(int y, int z) {
double n = Math.PI - (2.0 * Math.PI * y) / Math.pow(2.0, z);
return Math.toDegrees(Math.atan(Math.sinh(n)));
}
#Override
public void start(Stage stage) throws Exception {
Canvas canvas = new Canvas(Config.xSize, Config.ySize);
GraphicsContext gc = canvas.getGraphicsContext2D();
int [] aa =getTileNumber(51.401968,16.205556, 18);
getTiles(51.401968,16.205556);
getImgPositionAndURLsPath(list);
ExecutorService executor = Executors.newFixedThreadPool(10);
ArrayList<UtlToImageConverter> threadList = new ArrayList<>();
for(PositionTilesAndURLPaths url : positionTilesAndURLPathsList){
threadList.add(new UtlToImageConverter(url.getPath()));
}
try {
executor.invokeAll(threadList);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(imgCache.size());
System.out.println( aa[0] + " " + aa[1] );
for(PositionTilesAndURLPaths pos : getImgPositionAndURLsPath(list)){
gc.drawImage(imgCache.get(pos.getPath()),Config.xSize/2-pos.getX()-Config.imgSize/2 ,(Config.ySize/2)- pos.getY()-Config.imgSize/2, Config.imgSize, Config.imgSize);
}
gc.drawImage(bus,Config.xSize/2-Config.imgSize/2-Config.markWidth/2+(int)positionX, Config.ySize/2+(int)positionY-Config.imgSize/2-Config.markHeight/2, Config.markWidth, Config.markHeight);
Pane root = new Pane();
root.getChildren().add(canvas);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args)
{
Application.launch(args);
}
}
So in a game I am making, I'm trying to send over an ArrayList of type Troop and ArrayList of type Tower over a socket, with both class Troop and Tower having a buffered Image. The game runs at 60 fps, and each time it sends over the two ArrayLists between both the server and client in the updateConnection() method. When I pulled out the Troop class and the Server and Client Classes, I am successfully able to send over the ArrayLists, but I get an error saying Troop is not sterilizable when it runs in the game. Below I included the Troop class, the server and client classes, the two classes that ran the test sending and receiving, and the method updateConnection() in the Game class:
public class Server{
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
JTextArea t;
JFrame f;
//constructor
public Server(){
f = new JFrame();
f.getContentPane().setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
t = new JTextArea();
f.add(t, BorderLayout.CENTER);
f.setVisible(true);
try{
server = new ServerSocket(8790, 10); //8798 is a dummy port for testing, this can be changed. The 100 is the maximum people waiting to connect.
try{
//Trying to connect and have conversation
waitForConnection();
setupStreams();
}catch(EOFException eofException){
//t.append("Connection was terminated");
}
} catch (IOException ioException){
ioException.printStackTrace();
}
}
//wait for connection, then display connection information
private void waitForConnection() throws IOException{
t.append(" Waiting for someone to connect...");
connection = server.accept();
t.append(" Now connected to " + connection.getInetAddress().getHostName());
}
//get stream to send and receive data
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
t.append(" Streams are now setup ");
f.setVisible(false);
f.dispose();
}
// input.readObject();
public void closeConnection(){
//t.append(" Closing Connections... ");
try{
output.close(); //Closes the output path to the client
input.close(); //Closes the input path to the server, from the client.
connection.close(); //Closes the connection between you can the client
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public ObjectOutputStream getOutput(){
return output;
}
public ObjectInputStream getInput(){
return input;
}
public void sendObjects(Object obj){
try {
output.writeObject(obj);
output.flush();
output.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
public Object receiveObjects(){
try{
return input.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
.
public class Client extends JFrame{
private static final long serialVersionUID = 1L;
private ObjectOutputStream output;
private ObjectInputStream input;
private String serverIP;
private Socket connection;
JTextArea t;
JFrame f;
//constructor
public Client(String host){
serverIP = host;
f = new JFrame();
f.getContentPane().setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
t = new JTextArea();
f.add(t, BorderLayout.CENTER);
f.setVisible(true);
try{
connectToServer();
setupStreams();
}catch(EOFException eofException){
//t.append("Connection was terminated");
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public Client(){
serverIP = "127.0.0.1";
f = new JFrame();
f.getContentPane().setPreferredSize(new Dimension(300, 300));
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
t = new JTextArea();
f.add(t, BorderLayout.CENTER);
f.setVisible(true);
try{
connectToServer();
setupStreams();
}catch(EOFException eofException){
//t.append("Connection was terminated");
}catch(IOException ioException){
ioException.printStackTrace();
}
}
//connect to server
private void connectToServer() throws IOException{
t.append("Attempting connection...");
connection = new Socket(InetAddress.getByName(serverIP), 8790);
t.append("Connection Established! Connected to: " + connection.getInetAddress().getHostName());
}
//set up streams
private void setupStreams() throws IOException{
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
t.append(" The streams are now set up!");
f.setVisible(false);
f.dispose();
}
//Close connection
public void closeConnection(){
//t.append(" Closing the connection!");
try{
output.close();
input.close();
connection.close();
}catch(IOException ioException){
ioException.printStackTrace();
}
}
public ObjectOutputStream getOutput(){
return output;
}
public ObjectInputStream getInput(){
return input;
}
public void sendObjects(Object obj){
try {
output.writeObject(obj);
output.flush();
output.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
public Object receiveObjects(){
try{
return input.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}
.
public class Troop implements Serializable{
private int x;
private int y;
private int health;
private int movSpeed;
private int movSpeedx;
private int movSpeedy;
private int cost;
private long deployCoolDown;
private int level;
private transient BufferedImage image;
private int size = 16;
private Handler handler;
/**
*
* #param x
* #param y
* #param level
* #param health
* #param movSpeed
* #param movSpeedx
* #param movSpeedy
* #param cost
* #param deployCoolDown
* #param image
*
*/
public Troop(int x, int y, int level, int health, int movSpeed, int movSpeedx, int movSpeedy, int cost, long deployCoolDown, BufferedImage image, Handler handler){
this.x = x;
this.y = y;
this.level = level;
this.health = health;
this.movSpeed = movSpeed;
this.movSpeedx = -movSpeed;
this.movSpeedy = movSpeedy;
this.cost = cost;
this.deployCoolDown = deployCoolDown;
this.image = image;
this.handler = handler;
}
public void update(){
Move();
if(health <= 0){
handler.getTroops().remove(this);
}
}
public void checkX(){
int z = 0;
int tempMovSpeed = movSpeed;
if(tempMovSpeed> 0){ //moving down
int ty = (int) (y + tempMovSpeed + size + size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x) / Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size) / Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size/2) / Tile.TILE_HEIGHT,ty)){
z = 1;
}else{
//System.out.println("collision moving down");
}
}
tempMovSpeed = -movSpeed;
if(tempMovSpeed < 0){ // up
int ty = (int) (y + tempMovSpeed - size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x) / Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size) / Tile.TILE_HEIGHT,ty) &&
!collisionWithTile((int) (x + size/2) / Tile.TILE_HEIGHT,ty)){
if(z == 1){
z = 3;
}
else{
z = 2;
}
}else{
//System.out.println("collision moving up");
}
}
//System.out.println(z);
if(z == 0){
//System.out.println("dead end?");
}
else if(z == 1){
movSpeedy = movSpeed;
}
else if(z == 2){
movSpeedy = -movSpeed;
}
else if(z == 3){
Random r = new Random();
int q = r.nextInt(2);
if(q == 0){
movSpeedy = movSpeed;
}
else{
movSpeedy = -movSpeed;
}
}
}
public void checkY(){
int z = 0;
int tempMovSpeed = movSpeed;
int tx = (int) (x + tempMovSpeed + size + size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2) / Tile.TILE_HEIGHT)){
z = 1;
}
tempMovSpeed = -movSpeed;
tx = (int) (x + tempMovSpeed - size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2) / Tile.TILE_HEIGHT)){
if(z != 1){
z = 2;
}
else{
z = 3;
}
}
if(z == 0){
//System.out.println("dead end");
}
else if(z == 1){
movSpeedx = movSpeed;
}
else if(z == 2){
movSpeedx = -movSpeed;
}
else{
Random r = new Random();
int q = r.nextInt(1);
if(q == 0){
movSpeedx = movSpeed;
}
else{
movSpeedx = -movSpeed;
}
}
}
protected boolean collisionWithTile(int x, int y){
return !handler.getWorlds().get(handler.getGame().getLevel()).getTile(x, y).isPath();
}
public void render(Graphics g){
g.setColor(Color.GREEN);
g.fillRect(x, y, size, size);
}
public void Move(){
if(movSpeedx > 0){ //moving right
int tx = (int) (x + movSpeedx + size + size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2) / Tile.TILE_HEIGHT)){
x += movSpeedx;
}else{
x = tx * Tile.TILE_WIDTH - 3 * size /2;
checkX();
movSpeedx = 0;
}
}
else if(movSpeedx < 0){ // left
int tx = (int) (x + movSpeedx - size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile(tx, (int) (y) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size) / Tile.TILE_HEIGHT) &&
!collisionWithTile(tx, (int) (y + size/2) / Tile.TILE_HEIGHT)){
x += movSpeedx;
}else{
x = tx * Tile.TILE_WIDTH + Tile.TILE_WIDTH + size/2;
checkX();
movSpeedx = 0;
}
}
if(movSpeedy > 0){ //moving down
int ty = (int) (y + movSpeedy + size + size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x) / Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size) / Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size/2) / Tile.TILE_HEIGHT, ty)){
y += movSpeedy;
}else{
//System.out.println("collision");
y = ty * Tile.TILE_WIDTH - 3 * size /2;
movSpeedy = 0;
checkY();
}
}
else if(movSpeedy < 0){ // up
int ty = (int) (y + movSpeedy - size/2) / Tile.TILE_WIDTH;
if(!collisionWithTile((int) (x) / Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size) / Tile.TILE_HEIGHT, ty) &&
!collisionWithTile((int) (x + size/2) / Tile.TILE_HEIGHT, ty)){
y += movSpeedy;
}else{
y = ty * Tile.TILE_WIDTH + Tile.TILE_WIDTH + size/2;
movSpeedy = 0;
checkY();
}
}
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getSize(){
return size;
}
public int getMovSpeed() {
return movSpeed;
}
public void setMovSpeed(int movSpeed) {
this.movSpeed = movSpeed;
}
public int getHealth() {
return health;
}
public void changeHealth(int health) {
this.health += health;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
public long getDeployCoolDown() {
return deployCoolDown;
}
public void setDeployCoolDown(int deployCoolDown) {
this.deployCoolDown = deployCoolDown;
}
private void writeObject(ObjectOutputStream out)throws IOException{
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
in.defaultReadObject();
}
}
The method from Game (which is called 60 times a second):
private void updateConnection(){
if(isClientActive()){
if(player.getType() == 0){
client.sendObjects(towers);
System.out.println("sent towers: " + towers.size());
}else{
client.sendObjects(troops);
System.out.println("sent troops: " + troops.size());
}
ArrayList<Object> obj = (ArrayList<Object>)client.receiveObjects();
System.out.println("obj: " +obj.size());
if(obj != null && obj.size() > 0){
if (obj.get(0) instanceof Troop) {
mendTroops(obj);
}else if(obj.get(0) instanceof Troop){
mendTowers(obj);
}
}
}else if(isServerActive()){
if(player.getType() == 0){
server.sendObjects(towers);
System.out.println("sent towers: " + towers.size());
}else{
server.sendObjects(troops);
System.out.println("sent troops: " + troops.size());
}
ArrayList<Object> obj = (ArrayList<Object>)server.receiveObjects();
System.out.println("obj: " +obj.size());
if(obj != null && obj.size() > 0){
if (obj.get(0) instanceof Troop) {
mendTroops(obj);
}else if(obj.get(0) instanceof Troop){
mendTowers(obj);
}
}
}
}
Here is the two main methods I call to test the server, client, and troop classes:
public static void main(String[] args){
Server s = new Server();
ArrayList<Troop> troopsArray = new ArrayList<Troop>();
troopsArray.add(new Goblin(1,1,1));
troopsArray.add(new Goblin(2,2,2));
s.sendObject(troopsArray);
}
public static void main(String[] args){
Client c = new Client();
while(true){
ArrayList<Troop> troop2 = (ArrayList<Troop>)c.receiveObjects();
JOptionPane.showMessageDialog(null, troop2.get(1).getX());
}
}
Here is the requested Handler code:
public class Handler implements Serializable{
private Game game;
private transient Player player;
private transient ArrayList<Tower> towers;
private transient ArrayList<Troop> troops;
private transient Screen screen;
private transient Frame frame;
private transient Menu menu;
private ArrayList<Worlds> worlds;
public Handler(Game game, Player player, ArrayList<Tower> towers, ArrayList<Troop> troops, Screen screen, Frame frame, Menu menu, ArrayList<Worlds> worlds){
this.game = game;
this.player = player;
this.towers = towers;
this.troops = troops;
this.screen = screen;
this.frame = frame;
this.menu = menu;
this.worlds = worlds;
}
public Server getServer(){
return game.getServer();
}
public Client getClient(){
return game.getClient();
}
public ArrayList<Worlds> getWorlds() {
return worlds;
}
public Game getGame() {
return game;
}
public Player getPlayer() {
return player;
}
public ArrayList<Tower> getTowers() {
return towers;
}
public ArrayList<Troop> getTroops() {
return troops;
}
public Screen getScreen() {
return screen;
}
public Frame getFrame() {
return frame;
}
public Menu getMenu() {
return menu;
}
public boolean towerCollisionWithTile(int x, int y){
return worlds.get(game.getLevel()).getTile(x, y).isTowerNotPlaceable();
}
}
Worlds class:
public class Worlds implements Serializable{
private int width = 40;
private int height = 20; //in tiles
private int spawnX, spawnY;
private int[][] tiles;
public Worlds(String path){
loadWorld(path);
}
public Tile getTile(int x, int y){
if(x < 0 || y < 0 || x >= width || y >= height)
return Tile.grassTile;
Tile t = Tile.tiles[tiles[x][y]];
if(t == null)
return Tile.grassTile;
return t;
}
public void render(Graphics g){
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
getTile(x, y).render(g, (int) (x * Tile.TILE_WIDTH),
(int) (y* Tile.TILE_HEIGHT));
}
}
}
private void loadWorld(String path){
String file = Utils.loadFileAsString(path);
String [] tokens = file.split("\\s");
tiles = new int[width][height];
for(int y = 0; y < height; y++){
for(int x = 0; x < width; x++){
tiles[x][y] = Utils.parseInt(tokens[(x + y * width)]);
}
}
}
}
Sorry if I posted too much code, but I'd rather have a little too much, than not enough. If it is needed I can post the contents of the console for the Errors. I appreciate the help.
The Handler appears to be this which is not serializable. You will need to make it transient like the BufferedImage.
Credit goes to both Ian and CConard96. The problem was, while the class I was trying to send over was serializable, the references it made were not. In order to reduce what I was sending over the socket (and thus simplify it so that less needed to be serializable) I was able to fix the problem by using static references, eliminating them (the non-serialized classes) from being written by the ObjectOutputStream.
While transient can work, it is not ideal in this situation. It will cause the sent object to have a null reference to anything transient. So the Handler variable as well as buffered Image needed to be handed differently.
I have 3 classes. One class is my mainframe, another class is my JInternalFrame and also my Observer and the third class does a simulation with a field ob buttons and that one is also my observable class.
Basically I made a button in my observer that copies itself. That includes the add to the desktoppane and the addObserver function of my observable class.
The clone of my observer should also observer the very same observable. So if I interact with the one JInternalFrame, it also changes stuff for the other InternalFrame. It should act like a mirror. (Actually the copy should have like diffrent color buttons and a diffrent orientation but I think that should not be a problem to implement, as soon as I successfully could mirror my Observer)
So since I am using the Observable pattern, I also have to implement the "update" function in my Observer class. I did that and I works like a charm. But when I copy my JInternalFrame, the new InternalFrame observes the Observable(Simulation), but my original JInternalFrame loses the observable connection. It does not show buttons anymore etc.
What I tried: I created a second Observer/JInternalFrame class that extends my first Observer class. That did not work as well. I don't know if thats even a possibility to achieve what I want to.
Sorry for my non perfect english. Sorry for some german words that you might find in the code and sorry that I post so much code. But I am really uncertain right now where my mistake is since I tried to find the error for ours so far.
So here are 2 pictures for you:
First picture shows how my JInternalFrame looks like when I create it. Here everything works perfectly.
Second picture shows what it looks like when I click on the New View button. As already described. The original JInternalFrame does not show the simulation anymore. Although they are both observing the same Observable.
And here are my 3 imporant classes:
MainFrame:
public class LangtonsAmeise extends JFrame implements ActionListener {
JDesktopPane desk;
JPanel panelButtons;
JMenuBar jmb;
JMenu file, modus;
JMenuItem load, save, exit, mSetzen, mMalen, mLaufen;
JSlider slider;
static int xInt, yInt, xKindFrame = 450, yKindFrame = 450, xLocation,
yLocation, xMainFrame = 1000, yMainFrame = 900;
static boolean bSetzen = false, bMalen = false, running = true;
static JFileChooser fc;
Random randomGenerator = new Random();
JLabel xLabel, yLabel, speed, statusText, status;
JButton start, stop, addAnt;
JTextField xField, yField;
public LangtonsAmeise() {
// Desktop
desk = new JDesktopPane();
getContentPane().add(desk, BorderLayout.CENTER);
// File Chooser
fc = new JFileChooser(System.getProperty("user.dir"));
speed = new JLabel("Geschwindigkeit");
xLabel = new JLabel("x:");
yLabel = new JLabel("y:");
xLabel.setHorizontalAlignment(JLabel.RIGHT);
yLabel.setHorizontalAlignment(JLabel.RIGHT);
xLabel.setOpaque(true);
yLabel.setOpaque(true);
xField = new JTextField();
yField = new JTextField();
start = new JButton("Fenster erstellen");
stop = new JButton("Pause/Fortsetzen");
start.setMargin(new Insets(0, 0, 0, 0));
stop.setMargin(new Insets(0, 0, 0, 0));
// Buttons
panelButtons = new JPanel();
panelButtons.setLayout(new GridLayout());
panelButtons.add(start);
panelButtons.add(xLabel);
panelButtons.add(xField);
panelButtons.add(yLabel);
panelButtons.add(yField);
panelButtons.add(speed);
panelButtons.add(new Panel());
panelButtons.add(stop);
start.addActionListener(this);
stop.addActionListener(this);
add(panelButtons, BorderLayout.NORTH);
statusText = new JLabel("Status:");
status = new JLabel("Stopp");
// JMenuBar
jmb = new JMenuBar();
setJMenuBar(jmb);
file = new JMenu("File");
modus = new JMenu("Mode");
mLaufen = new JMenuItem("Laufen");
mMalen = new JMenuItem("Malen");
mSetzen = new JMenuItem("Setzen");
load = new JMenuItem("Simulation laden");
//save = new JMenuItem("Simulation speichern");
mSetzen.addActionListener(this);
mMalen.addActionListener(this);
mLaufen.addActionListener(this);
exit = new JMenuItem("Exit");
file.add(load);
file.addSeparator();
file.add(exit);
load.addActionListener(this);
modus.add(mLaufen);
modus.add(mSetzen);
modus.add(mMalen);
jmb.add(file);
jmb.add(modus);
for (int i = 0; i < 20; i++) {
jmb.add(new JLabel(" "));
}
jmb.add(statusText);
jmb.add(status);
setSize(new Dimension(xMainFrame, yMainFrame));
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width / 2 - this.getSize().width / 2, dim.height
/ 2 - this.getSize().height / 2);
xField.setText("5");
yField.setText("5");
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Fenster erstellen")) {
if (xField.getText().equals("") || yField.getText().equals("")) {
} else {
xInt = Integer.parseInt(xField.getText());
yInt = Integer.parseInt(yField.getText());
state s = new state();
kindFenster k = new kindFenster(s, this);
s.addObserver(k);
addChild(k);
s.startSimulation();
}
}
if (e.getActionCommand().equals("Pause/Fortsetzen")) {
running = !running;
System.out.println(running);
status.setText("Stopp");
}
if (e.getActionCommand().equals("Setzen")) {
status.setText("Setzen");
running = false;
bSetzen = true;
bMalen = false;
}
if (e.getActionCommand().equals("Laufen")) {
status.setText("Laufen");
running = true;
bSetzen = false;
bMalen = false;
}
if (e.getActionCommand().equals("Malen")) {
status.setText("Malen");
running = false;
bSetzen = false;
bMalen = true;
}
if (e.getActionCommand().equals("Simulation laden")) {
LangtonsAmeise.running = false;
InputStream fis = null;
try {
fc.showOpenDialog(null);
fis = new FileInputStream(fc.getSelectedFile().getPath());
ObjectInputStream ois = new ObjectInputStream(fis);
state s = (state) ois.readObject();
kindFenster k = new kindFenster(s, this);
s.addObserver(k);
addChild(k);
s.startSimulation();
} catch (IOException | ClassNotFoundException
| NullPointerException e1) {
LangtonsAmeise.running = true;
} finally {
try {
fis.close();
} catch (NullPointerException | IOException e1) {
LangtonsAmeise.running = true;
}
}
LangtonsAmeise.running = true;
}
}
public void addChild(JInternalFrame kind) {
xLocation = randomGenerator.nextInt(xMainFrame - xKindFrame);
yLocation = randomGenerator.nextInt(yMainFrame - yKindFrame - 100);
kind.setSize(370, 370);
kind.setLocation(xLocation, yLocation);
desk.add(kind);
kind.setVisible(true);
}
public static void main(String[] args) {
LangtonsAmeise hauptFenster = new LangtonsAmeise();
}
}
JInternalFrame:
public class kindFenster extends JInternalFrame implements ActionListener,
Serializable,Observer,Cloneable {
/**
*
*/
private static final long serialVersionUID = 8939449766068226519L;
static int nr = 0;
static int x,y,xScale,yScale,xFrame,yFrame;
state s;
ArrayList<ImageIcon> ameisen = new ArrayList<ImageIcon>();
JFileChooser fc;
LangtonsAmeise la;
Color alteFarbe, neueFarbe;
JButton save, addAnt, newView;
JPanel panelButtonsKind;
JSlider sliderKind;
public JPanel panelSpielfeld,panelSpielfeldKopie;
JButton[] jbArrayy;
static SetzenActionListener sal = new SetzenActionListener();
static MouseMotionActionListener mmal = new MouseMotionActionListener();
public kindFenster(state s,LangtonsAmeise la) {
super("Kind " + (++nr), true, true, true, true);
setLayout(new BorderLayout());
this.s=s;
jbArrayy=new JButton[s.jbArrayy.length];
for (int b = 1; b<s.jbArrayy.length;b++) {
this.jbArrayy[b] = s.jbArrayy[b];
}
this.la=la;
setSize(new Dimension(xFrame, yFrame));
this.addInternalFrameListener(listener);
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
panelSpielfeld = new JPanel();
panelSpielfeld.setLayout(new GridLayout(s.y, s.x));
panelButtonsKind = new JPanel();
panelButtonsKind.setLayout(new GridLayout(1, 3));
save = new JButton("<html>Save<br>simulation</html>");
addAnt = new JButton("<html>Add<br>ant</html>");
newView = new JButton("<html>New<br>View</html>");
save.setActionCommand("save");
addAnt.setActionCommand("addAnt");
newView.setActionCommand("newView");
save.setMargin(new Insets(0, 0, 0, 0));
addAnt.setMargin(new Insets(0, 0, 0, 0));
addAnt.addActionListener(this);
save.addActionListener(this);
newView.addActionListener(this);
sliderKind = new JSlider(JSlider.HORIZONTAL, 1, 9, 5);
sliderKind.setSnapToTicks(true);
sliderKind.setPaintTicks(true);
sliderKind.setPaintTrack(true);
sliderKind.setMajorTickSpacing(1);
sliderKind.setPaintLabels(true);
sliderKind.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
if (!source.getValueIsAdjusting()) {
int speed = source.getValue();
state.sleeptime = 1000 / speed;
}
}
});
panelButtonsKind.add(save);
panelButtonsKind.add(newView);
panelButtonsKind.add(sliderKind);
panelButtonsKind.add(addAnt);
add(panelButtonsKind, BorderLayout.NORTH);
add(panelSpielfeld, BorderLayout.CENTER);
this.addComponentListener(new MyComponentAdapter());
for (int i = 1 ; i<jbArrayy.length;i++) {
panelSpielfeld.add(jbArrayy[i]);
}
}
// I have been trying around to change the orientation of the buttons in the copy of the frame
public void secondViewFrameSettings() {
int temp;
for (int i = 1; i<=x;i++) {
for (int k = 0; k<y;k++) {
temp = i+(k*x);
panelSpielfeldKopie.add(s.jbArrayy[temp]);
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("addAnt")) {
s.addAnt();
}
if (e.getActionCommand().equals("newView")){
kindFenster kk = new kindFenster(s,la);
s.addObserver(kk);
la.addChild(kk);
}
if (e.getActionCommand().equals("save")) {
OutputStream fos = null;
try {
LangtonsAmeise.running=false;
try {
fc = new JFileChooser(System.getProperty("user.dir"));
fc.showSaveDialog(null);
LangtonsAmeise.fc.setCurrentDirectory(fc.getSelectedFile());
fos = new FileOutputStream(fc.getSelectedFile());
ObjectOutputStream o = new ObjectOutputStream(fos);
o.writeObject(s);
} catch (NullPointerException e2) {
System.out.println("Fehler beim Auswählen der Datei. Wenden Sie sich an den Entwickler.");
}
} catch (IOException e1) {
LangtonsAmeise.running=true;
System.err.println(e1);
} finally {
try {
fos.close();
} catch (NullPointerException | IOException e1) {
LangtonsAmeise.running=true;
}
LangtonsAmeise.running=true;
}
LangtonsAmeise.running=true;
}
}
InternalFrameListener listener = new InternalFrameAdapter() {
public void internalFrameClosing(InternalFrameEvent e) {
e.getInternalFrame().dispose();
s.simulation.suspend();
}
};
class MyComponentAdapter extends ComponentAdapter {
public void componentResized(ComponentEvent e) {
//Ameisenbilder an die Buttongrößen anpassen
xScale=s.jbArrayy[1].getSize().width;
yScale=s.jbArrayy[1].getSize().height;
s.ameisen.clear();
s.ameisen.add(new ImageIcon(new ImageIcon("ameise.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise90.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise180.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
s.ameisen.add(new ImageIcon(new ImageIcon("ameise270.gif")
.getImage().getScaledInstance(xScale, yScale,
Image.SCALE_SMOOTH)));
}
}
public void update(Observable o, Object arg) {
if (o == s) {
for (int i = 1;i<s.jbArrayy.length;i++) {
jbArrayy[i].setBackground(s.jbArrayy[i].getBackground());
}
}
}
}
class SetzenActionListener implements ActionListener,Serializable {
JButton source;
#Override
public void actionPerformed(ActionEvent e) {
source = (JButton) e.getSource();
if (LangtonsAmeise.bSetzen == true) {
if (source.getBackground().equals(Color.GREEN)) {
source.setBackground(Color.WHITE);
} else {
source.setBackground(Color.GREEN);
}
}
}
}
class MouseMotionActionListener extends MouseInputAdapter implements Serializable {
boolean dragged = false;
JButton tempJButton = new JButton();
public void mouseEntered(MouseEvent e) {
if (LangtonsAmeise.bMalen == true && dragged == true) {
((JButton) e.getSource()).setBackground(Color.GREEN);
}
}
public void mouseDragged(MouseEvent e) {
dragged = true;
}
public void mouseReleased(MouseEvent e) {
dragged = false;
}
}
Observable class:
public class state extends Observable implements Serializable {
/**
*
*/
private static final long serialVersionUID = 450773214079105589L;
int[] obRand, reRand, unRand, liRand;
int x, y, temp;
static int sleeptime = 200;
Color background;
int posAmeise, aktuellesIcon = 1, altePosAmeise, xScale, yScale;
Color alteFarbe, neueFarbe, color1, color2;
ArrayList<JButton> jbSer = new ArrayList<JButton>();
private List<Ant> ants = new ArrayList<Ant>();
ArrayList<ImageIcon> ameisen = new ArrayList<>();
JButton[] jbArrayy;
transient Thread simulation;
public state() {
this.x = LangtonsAmeise.xInt;
this.y = LangtonsAmeise.yInt;
color1 = Color.WHITE;
color2 = Color.GREEN;
jbArrayy = new JButton[x * y + 1];
initializeBorders();
initializeAntsImages();
initializeSimulationButtons();
xScale = jbArrayy[1].getSize().width;
yScale = jbArrayy[1].getSize().height;
// Startpunkt für die Ameise festlegen
posAmeise = (((x / 2) * y) - y / 2);
background = jbArrayy[posAmeise].getBackground();
ants.add(new Ant(this));
}
public void initializeAntsImages() {
ameisen.add(new ImageIcon(new ImageIcon("ameise.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise90.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise180.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
ameisen.add(new ImageIcon(new ImageIcon("ameise270.gif").getImage()
.getScaledInstance(LangtonsAmeise.xKindFrame / x,
LangtonsAmeise.yKindFrame / y, Image.SCALE_SMOOTH)));
}
// Alle Buttons für das Simulationsfeld werden erstellt
public void initializeSimulationButtons() {
jbArrayy[0] = new JButton();
for (int i = 1; i < jbArrayy.length; i++) {
jbArrayy[i] = new JButton();
jbArrayy[i].setBackground(color1);
jbArrayy[i].addActionListener(kindFenster.sal);
jbArrayy[i].addMouseListener(kindFenster.mmal);
jbArrayy[i].addMouseMotionListener(kindFenster.mmal);
}
}
// Ränderindex in Array schreiben
public void initializeBorders() {
reRand = new int[y];
liRand = new int[y];
obRand = new int[x];
unRand = new int[x];
for (int i = 0; i < x; i++) {
obRand[i] = i + 1;
unRand[i] = (x * y - x) + i + 1;
}
for (int i = 1; i <= y; i++) {
reRand[i - 1] = i * x;
liRand[i - 1] = i * x - (x - 1);
}
}
public void initializeSimulation() {
if (simulation != null && simulation.isAlive()) {
simulation.stop();
}
simulation = new Thread() {
#Override
public void run() {
super.run();
while (true) {
try {
sleep(300);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
while (LangtonsAmeise.running && countObservers() > 0) {
try {
Thread.sleep(sleeptime);
for (Ant a : ants) {
move(a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
}
public void startSimulation() {
initializeSimulation();
simulation.start();
}
public void changeColor(int altePos, Color c) {
jbArrayy[altePos].setBackground(c);
}
public void addAnt() {
ants.add(new Ant(this));
}
public void changeIcon(boolean k, Ant a) {
int g = (k == true) ? 1 : -1;
if (a.aktuellesIcon + g < 0) {
a.aktuellesIcon = 3;
} else if (a.aktuellesIcon + g > 3) {
a.aktuellesIcon = 0;
} else {
a.aktuellesIcon += g;
}
jbArrayy[a.posAmeise].setIcon(ameisen.get(a.aktuellesIcon));
setChanged();
notifyObservers();
}
public void rightCheck(Ant a) {
if (checkInArray(a.posAmeise, reRand)) {
a.posAmeise -= x - 1;
} else {
a.posAmeise += 1;
}
}
public void leftCheck(Ant a) {
if (checkInArray(a.posAmeise, liRand)) {
a.posAmeise += x - 1;
} else {
a.posAmeise -= 1;
}
}
public void upCheck(Ant a) {
if (checkInArray(a.posAmeise, obRand)) {
a.posAmeise += (y - 1) * x;
} else {
a.posAmeise -= x;
}
}
public void downCheck(Ant a) {
if (checkInArray(a.posAmeise, unRand)) {
a.posAmeise -= (y - 1) * x;
} else {
a.posAmeise += x;
}
}
public void checkAmeisenSize(Ant a) {
while (!(ameisen.size() == 4)) {
}
;
}
public static boolean checkInArray(int currentState, int[] myArray) {
int i = 0;
for (; i < myArray.length; i++) {
if (myArray[i] == currentState)
break;
}
return i != myArray.length;
}
public ImageIcon getAntImage() {
return ameisen.get(aktuellesIcon);
}
public void move(Ant a) throws InterruptedException {
try {
a.altePosAmeise = a.posAmeise;
a.alteFarbe = jbArrayy[a.posAmeise].getBackground();
if (a.alteFarbe.equals(Color.GREEN) && ameisen.size() == 4) {
if (a.aktuellesIcon == 0) {
checkAmeisenSize(a);
rightCheck(a);
} else if (a.aktuellesIcon == 1) {
checkAmeisenSize(a);
downCheck(a);
} else if (a.aktuellesIcon == 2) {
checkAmeisenSize(a);
leftCheck(a);
} else if (a.aktuellesIcon == 3) {
checkAmeisenSize(a);
upCheck(a);
}
changeIcon(true, a);
changeColor(a.altePosAmeise, Color.WHITE);
} else if (a.alteFarbe.equals(Color.WHITE) && ameisen.size() == 4) {
if (a.aktuellesIcon == 0) {
checkAmeisenSize(a);
leftCheck(a);
} else if (a.aktuellesIcon == 1) {
checkAmeisenSize(a);
upCheck(a);
} else if (a.aktuellesIcon == 2) {
checkAmeisenSize(a);
rightCheck(a);
} else if (a.aktuellesIcon == 3) {
checkAmeisenSize(a);
downCheck(a);
}
changeIcon(false, a);
changeColor(a.altePosAmeise, Color.GREEN);
setChanged();
notifyObservers();
}
jbArrayy[a.altePosAmeise].setIcon(new ImageIcon());
} catch (IndexOutOfBoundsException e) {
move(a);
}
}
}
Edit: Ant Class
import java.awt.Color;
import java.awt.Image;
import java.io.Serializable;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Ant implements Serializable {
int posAmeise, aktuellesIcon = 1, altePosAmeise;
Color alteFarbe, neueFarbe;
ArrayList<ImageIcon> ameisen = new ArrayList<>();
public Ant(state s) {
this.posAmeise = s.posAmeise;
s.jbArrayy[posAmeise].setIcon(s.ameisen.get(aktuellesIcon));
}
}