Problem with JScrollBar Display - java

I have added the following code for displaying a scrollbar to my textfield. But it still does not appear. Can someone please help me with this problem. I am unable to figure out where error is occuring:
public JTextArea talkArea = new JTextArea();
public JScrollPane talkAreaScrollPane = new JScrollPane(talkArea);
this.getContentPane(talkArea,null);
this.getContentPane(talkAreaScrollPane,null);
The code for the whole file is as follows and it compiles properly without giving error:
/*
* Client.java
*
*/
package ChatClientRMI;
import javax.naming.*;
import java.rmi.RemoteException;
import javax.rmi.PortableRemoteObject;
import java.rmi.RMISecurityManager;
import ChatServerRMI.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
public class Client extends JFrame implements Runnable, ActionListener {
private static final String connectStr = "Connect";
private static final String disconnectStr = "Disonnect";
private String _nickname;
private Thread _thread;
private Context _initialContext;
private JTextField inputField = new JTextField();
public JTextArea talkArea = new JTextArea;
JScrollPane talkAreaScrollPane = new JScrollPane(talkArea);
private JButton _connectButton;
private JButton _disconnectButton;
private Vector serverVector = new Vector();
private JList serverList = new JList(serverVector);
ChatRoom chatroom = null;
String chatroomName;
Client myFrame = this;
MyActionListener myActionListener = new MyActionListener();
boolean loaded = false;
static int REFRESH_TIME = 200;
// a timer for refresh graphic area
javax.swing.Timer frameTimer =
new javax.swing.Timer(REFRESH_TIME, myActionListener);
// client area info
public static int CLIENT_WIDTH = 800;
public static int CLIENT_HEIGHT = 600;
// left panel info
public static int LEFT_PANEL_WIDTH = 120;
public static int LEFT_PANEL_HEIGHT = 420;
public static int LEFT_PANEL_LEFT = 20;
public static int LEFT_PANEL_TOP = 20;
// graphic area info
public static int GRAPHIC_TOP = 30;
public static int GRAPHIC_LEFT = 30;
public static int GRAPHIC_WIDTH = 400;
public static int GRAPHIC_HEIGHT = 300;
// talk area info
public static int TALK_TOP = GRAPHIC_TOP + GRAPHIC_HEIGHT + 5;
public static int TALK_LEFT = GRAPHIC_LEFT;
public static int TALK_WIDTH = GRAPHIC_WIDTH;
public static int TALK_HEIGHT = 175;
// input field info
public static int INPUT_TOP = TALK_TOP + TALK_HEIGHT + 25;
public static int INPUT_LEFT = GRAPHIC_LEFT;
public static int INPUT_WIDTH = GRAPHIC_WIDTH;
public static int INPUT_HEIGHT = 20;
// server list info
public static int SERVER_LIST_TOP = GRAPHIC_TOP;
public static int SERVER_LIST_LEFT = GRAPHIC_LEFT + GRAPHIC_WIDTH + 160;
public static int SERVER_LIST_WIDTH = 120;
public static int SERVER_LIST_HEIGHT = GRAPHIC_HEIGHT; // 420;
// user list info
public static int USER_LIST_TOP = 20;
public static int USER_LIST_LEFT = GRAPHIC_LEFT + GRAPHIC_WIDTH + 10;
public static int USER_LIST_WIDTH = 120;
public static int USER_LIST_HEIGHT = 420;
public static int SHADOW_WIDTH = 5;
// background color
static Color backColor = new Color(130, 60, 170);
// command label
static final String CMD_LABEL[] =
{ "change icon", "query friend", "change location", "open room",
"query hero", "help", "temp leave", "leave" };
// icon info
public static final int MAX_ICONS = 100;
public static final String ICON_FILENAME = "icons.gif";
public static int ICON_WIDTH = 32;
public static int ICON_HEIGHT = 32;
Image icons[] = new Image[MAX_ICONS];
int totalIcons = 16;
static String BACKIMG_FILENAME[] =
{ "back0.jpg", "back1.jpg", "back2.jpg", "back3.jpg" };
Image backImg = null;
Image leftPanelImg = null;
Image graphicImg = null;
Image userListImg = null;
Image serverListImg = null;
// user info
static int MAX_USERS = 100;
UserInfo userInfo[] = new UserInfo[MAX_USERS];
int totalUsers = 0;
int myIdx = 0;
Hashtable users = new Hashtable();
// say delay
static int SAY_TIME = 15;
// say rectangle's width
static int SAY_WIDTH = 100;
// move step
static int ONE_STEP = 10;
boolean endChat = true;
boolean moveEnd = true;
boolean sayEnd = true;
int enterListIndex = -1;
int exitListIndex = -1;
/** Creates new ChatClient */
public Client(String name) {
super(name);
_nickname = name;
try {
_initialContext = new InitialContext();
} catch (Exception e) {
System.out.println(e);
}
// Create and install a security manager
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
setSize(new Dimension(CLIENT_WIDTH, CLIENT_HEIGHT));
this.getContentPane().setLayout(null);
this.getContentPane().setBackground(backColor);
talkArea.setEditable(false);
talkArea.setBackground(Color.white);
talkArea.setBounds(new Rectangle(TALK_LEFT, TALK_TOP, TALK_WIDTH,
TALK_HEIGHT));
this.getContentPane().add(talkArea, null);
// set input area
inputField.setBackground(Color.white);
inputField.setBounds(new Rectangle(INPUT_LEFT, INPUT_TOP, INPUT_WIDTH,
INPUT_HEIGHT));
inputField.addActionListener(this);
this.getContentPane().add(inputField, null);
this.getContentPane().add(talkAreaScrollPane, null);
// connect button
_connectButton = new JButton(connectStr);
_connectButton.setBounds(new Rectangle(600, 400, 100, 30));
_connectButton.addActionListener(this);
this.getContentPane().add(_connectButton);
// disconnect button
_disconnectButton = new JButton(disconnectStr);
_disconnectButton.setBounds(new Rectangle(600, 450, 100, 30));
_disconnectButton.setEnabled(false);
// _disconnectButton.addActionListener(this);
this.getContentPane().add(_disconnectButton);
// testButton = new JButton("test");
// testButton.setBounds(new Rectangle(600,500,100,30));
// testButton.addActionListener(this);
// this.getContentPane().add(testButton);
for (int i = 0; i < 5; i++) {
serverVector.add("ChatRoom" + i);
}
serverList.setBackground(new Color(190, 180, 255));
serverList.setBounds(new Rectangle(SERVER_LIST_LEFT + 2,
SERVER_LIST_TOP + 40, SERVER_LIST_WIDTH - SHADOW_WIDTH - 10,
SERVER_LIST_HEIGHT - 40 - 50));
serverList.setSelectedIndex(0);
serverList.setCellRenderer(new CustomCellRenderer());
this.getContentPane().add(serverList);
// add mouse listener for serverList
serverList.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(MouseEvent e) {
int index = serverList.locationToIndex(e.getPoint());
enterListIndex = index;
// setForeground(new Color(0,0,255));
System.out.println("you entered index " + index);
}
public void mouseExited(MouseEvent e) {
int index = serverList.locationToIndex(e.getPoint());
exitListIndex = index;
// setForeground(new Color(0,255,255));
System.out.println("you exited index " + index);
}
});
// add mouse listener
this.addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent event) {
mouseClick_performed(event);
}
});
// Always need this to enable closing the frame
this.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
if (endChat) {
System.exit(0);
return;
}
boolean success = false;
try {
success = chatroom.disconnect(_nickname);
} catch (java.rmi.RemoteException err) {
System.out.println(err);
}
if (success)
System.out.println("Disonnected...");
else
System.out.println("Not disconnected.");
System.exit(0);
}
});
// Wait for incoming requests
this.startThread();
// Enable GUI
this.setVisible(true);
// create offscreen images
leftPanelImg = createImage(LEFT_PANEL_WIDTH, LEFT_PANEL_HEIGHT);
graphicImg = createImage(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
userListImg = createImage(USER_LIST_WIDTH, USER_LIST_HEIGHT);
serverListImg = createImage(SERVER_LIST_WIDTH, SERVER_LIST_HEIGHT);
drawServerList();
serverList.repaint();
(new LoadImageThread()).load();
try {
_initialContext.rebind(_nickname, new ChatUserImpl(this));
} catch (Exception e) {
System.out.println(e);
}
}
public void actionPerformed(java.awt.event.ActionEvent evt) {
Object source = evt.getSource();
if (source == _connectButton) {
if (serverList.getSelectedIndex() == -1) {
JOptionPane.showMessageDialog(this, "please select a chatroom",
"Error Dialog", JOptionPane.ERROR_MESSAGE);
return;
}
_connectButton.removeActionListener(this);
_connectButton.setEnabled(false);
_disconnectButton.addActionListener(this);
_disconnectButton.setEnabled(true);
inputField.addActionListener(this);
chatroomName = (String) serverList.getSelectedValue();
int code = (new Random()).nextInt(totalIcons - 1);
boolean success = false;
try {
System.out.println("chat room name: " + chatroomName);
chatroom =
(ChatRoom) PortableRemoteObject.narrow(_initialContext
.lookup(chatroomName), ChatRoom.class);
success = chatroom.connect(_nickname, code);
} catch (Exception e) {
System.out.println("ChatUserClient exception: " + e.getMessage());
e.printStackTrace();
}
if (success) {
System.out.println("Connected...");
endChat = false;
frameTimer.start();
} else {
System.out
.println("Not connected: the selected nickname is in use. Please choose another nickname.");
}
} else if (source == _disconnectButton) {
_connectButton.addActionListener(this);
_connectButton.setEnabled(true);
_disconnectButton.removeActionListener(this);
_disconnectButton.setEnabled(false);
inputField.removeActionListener(this);
// clear everything
talkArea.setText("");
inputField.setText("");
if (backImg == null) {
Graphics g = graphicImg.getGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
getGraphics().drawImage(graphicImg, GRAPHIC_LEFT, GRAPHIC_TOP, this);
} else {
getGraphics().drawImage(backImg, GRAPHIC_LEFT, GRAPHIC_TOP, this);
}
users.clear();
if (endChat) {
return;
}
boolean success = false;
try {
success = chatroom.disconnect(_nickname);
} catch (java.rmi.RemoteException e) {
System.out.println(e);
}
if (success) {
endChat = true;
System.out.println("Disonnected...");
} else {
System.out.println("Not disconnected.");
}
} else if (source == inputField) {
String message = inputField.getText();
try {
chatroom.sendMessage(message, _nickname);
} catch (java.rmi.RemoteException e) {
System.out.println(e);
}
}
} // end actionperformed
public void startThread() {
_thread = new Thread(this);
_thread.start();
}
public void run() {
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
super.paint(g);
if (loaded) {
g.drawImage(graphicImg, GRAPHIC_LEFT, GRAPHIC_TOP, this);
g.drawImage(serverListImg, SERVER_LIST_LEFT, SERVER_LIST_TOP, this);
serverList.repaint();
}
}
// sgn func
public int sgn(int x) {
if (x > 0)
return 1;
if (x < 0)
return -1;
return 0;
}
// everyone move one step
public void moveOneStep() {
int count = 0;
int direction;
for (Enumeration e = users.elements(); e.hasMoreElements();) {
UserInfo p = (UserInfo) e.nextElement();
direction = sgn(p.dx - p.x);
if (direction == 0)
count++;
p.x += direction * ONE_STEP;
direction = sgn(p.dy - p.y);
if (direction == 0)
count++;
p.y += direction * ONE_STEP;
if (java.lang.Math.abs(p.x - p.dx) <= ONE_STEP)
p.x = p.dx;
if (java.lang.Math.abs(p.y - p.dy) <= ONE_STEP)
p.y = p.dy;
if (p.x <= ICON_WIDTH / 2) {
p.x = ICON_WIDTH / 2;
p.dx = p.x;
}
if (p.x >= GRAPHIC_WIDTH - ICON_WIDTH / 2) {
p.x = GRAPHIC_WIDTH - ICON_WIDTH / 2;
p.dx = p.x;
}
if (p.y <= ICON_HEIGHT / 2) {
p.y = ICON_HEIGHT / 2;
p.dy = p.y;
}
if (p.y >= GRAPHIC_HEIGHT - ICON_HEIGHT / 2) {
p.y = GRAPHIC_HEIGHT - ICON_HEIGHT / 2;
p.dy = p.y;
}
}
moveEnd = (count == users.size() * 2);
System.out.println("count = " + count);
System.out.println("size = " + users.size());
System.out.println("messgeEnd = " + moveEnd);
} // end of moveOneStep
// timer action
public void timer_actionPerformed() {
if (endChat)
return;
if (!moveEnd)
moveOneStep();
if (moveEnd && sayEnd)
return;
drawGraphicArea();
getGraphics().drawImage(graphicImg, GRAPHIC_LEFT, GRAPHIC_TOP, this);
}
// mouse event
public void mouseClick_performed(java.awt.event.MouseEvent event) {
if (endChat)
return;
// if (endChat == true || myIdx == -1) return;
// if (userInfo[myIdx].x < 0) return;
if (event.getID() == event.MOUSE_PRESSED) {
int x = event.getX();
int y = event.getY();
if (x < GRAPHIC_LEFT || x >= GRAPHIC_LEFT + GRAPHIC_WIDTH
|| y < GRAPHIC_TOP || y > GRAPHIC_TOP + GRAPHIC_HEIGHT)
return;
moveEnd = false;
UserInfo p = (UserInfo) users.get(_nickname);
p.dx = x - GRAPHIC_LEFT;
p.dy = y - GRAPHIC_TOP;
try {
chatroom.sendLocation(p.dx, p.dy, p.name);
} catch (java.rmi.RemoteException e) {
System.out.println(e);
}
// sendCmd(MsgType.MOVE, userInfo[myIdx].dx, userInfo[myIdx].dy);
}
}
public void printUserList() {
Enumeration usernames = users.keys();
while (usernames.hasMoreElements()) {
System.out.println("user name: " + usernames.nextElement());
}
}
// draw server list
public void drawServerList() {
Graphics g = serverListImg.getGraphics();
g.setColor(backColor);
g.fillRect(0, 0, SERVER_LIST_WIDTH, SERVER_LIST_HEIGHT);
g.setColor(Color.black);
g.fillRoundRect(5, 5, SERVER_LIST_WIDTH - SHADOW_WIDTH, SERVER_LIST_HEIGHT
- SHADOW_WIDTH, 30, 30);
g.setColor(new Color(190, 180, 255));
g.fillRoundRect(0, 0, SERVER_LIST_WIDTH - SHADOW_WIDTH, SERVER_LIST_HEIGHT
- SHADOW_WIDTH, 30, 30);
g.setColor(new Color(0, 0, 255));
g.drawRoundRect(0, 0, SERVER_LIST_WIDTH - SHADOW_WIDTH, SERVER_LIST_HEIGHT
- SHADOW_WIDTH, 30, 30);
g.setFont(new Font(g.getFont().getName(), g.getFont().getStyle(), 20));
g.setColor(Color.black);
FontMetrics fntM = g.getFontMetrics();
String s = new String("Server List");
int x = (SERVER_LIST_WIDTH - fntM.stringWidth(s)) / 2;
g.drawString(s, x, 30);
// update to screen
getGraphics().drawImage(serverListImg, SERVER_LIST_LEFT, SERVER_LIST_TOP,
this);
}
// draw graphic area
public synchronized void drawGraphicArea() {
Graphics g = graphicImg.getGraphics();
FontMetrics fntM = g.getFontMetrics();
if (backImg == null) {
g.setColor(Color.blue);
g.fillRect(0, 0, GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
} else {
g.drawImage(backImg, 0, 0, this);
}
// if (myIdx == -1) return ;
UserInfo p;
g.setFont(new Font(g.getFont().getName(), g.getFont().getStyle(), 12));
int count = 0;
for (Enumeration e = users.elements(); e.hasMoreElements();) {
// draw icon
p = (UserInfo) e.nextElement();
g.drawImage(icons[p.code], p.x - ICON_WIDTH / 2, p.y - ICON_HEIGHT / 2,
this);
// draw name
if (p.name.equals(_nickname))
g.setColor(Color.red);
else
g.setColor(Color.yellow);
int x = (p.x - fntM.stringWidth(p.name) / 2);
int y = (p.y + ICON_HEIGHT / 2);
g.fillRoundRect(x - 2, y, fntM.stringWidth(p.name) + 4, fntM.getHeight(),
10, 10);
g.setColor(Color.black);
g.drawRoundRect(x - 2, y, fntM.stringWidth(p.name) + 4, fntM.getHeight(),
10, 10);
g.drawString(p.name, x, y + fntM.getAscent());
// draw say
if (p.sayTime <= 0) {
count++;
continue;
}
String saySplit[] = new String[100];
int c = 0;
int st = 0, ed = 1;
while (ed <= p.say.length()) {
String s = p.say.substring(st, ed);
if (fntM.stringWidth(s) > SAY_WIDTH) {
saySplit[c] = p.say.substring(st, ed - 1);
c++;
st = ed - 1;
}
ed++;
}
saySplit[c] = p.say.substring(st, ed - 1);
c++;
x = p.x + ICON_WIDTH / 2 + 5;
y = p.y - ICON_HEIGHT / 2 + 5;
int w = ((c > 1) ? SAY_WIDTH : fntM.stringWidth(saySplit[0])) + 5;
int h = fntM.getHeight() * c + 5;
// draw say arrow
g.setColor(Color.green);
if (x + w >= GRAPHIC_WIDTH) {
x = p.x - ICON_WIDTH / 2 - w - 5;
Polygon polygon = new Polygon();
polygon.addPoint(p.x - ICON_WIDTH / 2, p.y - 5);
polygon.addPoint(p.x - ICON_WIDTH / 2 - 8, p.y - 10);
polygon.addPoint(p.x - ICON_WIDTH / 2 - 8, p.y - 4);
// p.addPoint(x + ICON_WIDTH/2, y - 5);
g.fillPolygon(polygon);
} else {
Polygon polygon = new Polygon();
polygon.addPoint(p.x + ICON_WIDTH / 2, p.y - 5);
polygon.addPoint(p.x + ICON_WIDTH / 2 + 8, p.y - 10);
polygon.addPoint(p.x + ICON_WIDTH / 2 + 8, p.y - 4);
// p.addPoint(x + ICON_WIDTH/2, y - 5);
g.fillPolygon(polygon);
}
g.fillRoundRect(x, y, w, h, 10, 10);
g.setColor(Color.black);
// g.drawRoundRect(x, y, w, h, 10, 10);
for (int j = 0; j < c; j++) {
g.drawString(saySplit[j], x + 2, y + 2 + j * fntM.getHeight()
+ fntM.getAscent());
}
p.sayTime--;
} // end of for
sayEnd = (count == users.size());
update(getGraphics());
} // end of drawGraphicArea
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == frameTimer) {
timer_actionPerformed();
return;
}
}
}
// ****************************************
// a load image thread class in applet class
// ****************************************
class LoadImageThread extends Thread {
public void load() {
this.start();
}
public void run() {
loadImages();
loaded = true;
try {
sleep(1000);
} catch (java.lang.InterruptedException e) {
}
if (backImg == null) {
Graphics g = graphicImg.getGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
(myFrame.getGraphics()).drawImage(graphicImg, GRAPHIC_LEFT,
GRAPHIC_TOP, myFrame);
} else {
myFrame.getGraphics().drawImage(backImg, GRAPHIC_LEFT, GRAPHIC_TOP,
myFrame);
}
}
// load all images
public void loadImages() {
Graphics g = graphicImg.getGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
g.setColor(Color.yellow);
g.setFont(new Font(g.getFont().getName(), g.getFont().getStyle(), 30));
g.drawString("loading, please wait ......", 30, 50);
(myFrame.getGraphics()).drawImage(graphicImg, GRAPHIC_LEFT, GRAPHIC_TOP,
myFrame);
MediaTracker m = new MediaTracker(myFrame);
for (int i = 0; i < totalIcons; i++) {
icons[i] = Toolkit.getDefaultToolkit().getImage(i + ".gif");
m.addImage(icons[i], 0);
}
try {
m.waitForAll();
} catch (InterruptedException e) {
System.out.println("can't read image from file");
}
}
} // end of LoadImage class
class CustomCellRenderer extends JLabel implements ListCellRenderer {
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
String s = value.toString();
setText(s);
// setIcon((s.length() > 10) ? longIcon : shortIcon);
if (isSelected) {
// setBackground(list.getSelectionBackground());
// setForeground(list.getSelectionForeground());
setForeground(new Color(0, 0, 255));
} else {
// setBackground(list.getBackground());
// setForeground(list.getForeground());
setForeground(new Color(0, 255, 255));
}
/*
* if ( index == enterListIndex ){ System.out.println("****************");
* setForeground(new Color(0,0,180)); } if ( index == exitListIndex ){
* System.out.println("---------------"); setForeground(new
* Color(0,255,255)); }
*/
setEnabled(list.isEnabled());
setFont(list.getFont());
return this;
}
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
// args[0] is user nickname
if (args.length != 1) {
System.out.println("Usage: ChatClient nickname");
System.exit(0);
}
Client clientFrame = new Client(args[0]);
}
}
Any idea???
Do I need to set any kind of visibility??
Thanks

No, add the textArea to the ScrollPane then put the ScrollPane in your panel.
As a side note I would suggest learning more about LayoutManagers. They are worth the learning curve.
Example:
//In a container that uses a BorderLayout:
textArea = new JTextArea(5, 30);
...
JScrollPane scrollPane = new JScrollPane(textArea);
...
setPreferredSize(new Dimension(450, 110));
...
add(scrollPane, BorderLayout.CENTER);
Taken from: How to use scroll panes

You're adding both the text area, AND the scrollpane containing it to the content pane.
you're also setting sizes on the textarea, but not the scrollpane. and since your layout is managing all the bounds, the scrollpane is probably 0x0 at 0,0
setSize(new Dimension(CLIENT_WIDTH, CLIENT_HEIGHT));
this.getContentPane().setLayout(null);
this.getContentPane().setBackground(backColor);
talkArea.setEditable(false);
talkArea.setBackground(Color.white);
talkArea.setBounds(new Rectangle(TALK_LEFT, TALK_TOP, TALK_WIDTH, TALK_HEIGHT));
this.getContentPane().add(talkArea, null); // <--- you want this inside the text area, not here!
// set input area
inputField.setBackground(Color.white);
inputField.setBounds(new Rectangle(INPUT_LEFT, INPUT_TOP, INPUT_WIDTH, INPUT_HEIGHT));
inputField.addActionListener(this);
this.getContentPane().add(inputField, null);
this.getContentPane().add(talkAreaScrollPane, null); // <--- you never set the size on here
why are you getting rid of the layout and then managing everything explicitly for size? this would be a lot simpler if you used something like borderlayout and preferred sizes and let those things manage bounds for you.

Related

How to make an interactive world map in Java Swing?

I want to write a program in Java Swing which will show the world map, where a user can click on each country(i.e each country is a button). I thought that the most convenient way to do it is to split a world map image into buttons, but I couldn't figure out how can I do this.
I looked at this question: Split image into clickable regions , the given answer there shows how to split the image into rectangles, but I have to split it into arbitrary shapes.
This is the image i want to work on:
A 'little' bit of number crunching can define areas or shapes of particular colors in an image. E.G. Starting with this:
Original image, cropped and reduced to a binary (2 color) image, then the oceans flood filled. All but the flood filling done in Java code not shown.
Then running the shape algorithm based on colors near white (be patient - it takes a while), will produce a series of areas used to render this over the top. A mouse motion listener has been added to color the area under the pointer to dark green.
This is the code that produces that image. The mouse pointer is currently pointing at China.
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.imageio.ImageIO;
/*
Outline code from:
https://stackoverflow.com/q/7218309/418556
*/
public class WorldMapArea {
private JComponent ui = null;
JLabel output = new JLabel();
public static final int SIZE = 750;
BufferedImage image;
Area area;
ArrayList<Shape> shapeList;
public WorldMapArea() {
try {
initUI();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public final void initUI() throws Exception {
if (ui != null) {
return;
}
URL url = new URL("https://i.stack.imgur.com/N4eOn.png");
image = ImageIO.read(url);
long then = System.currentTimeMillis();
System.out.println("" + then);
area = getOutline(Color.WHITE, image, 12);
long now = System.currentTimeMillis();
System.out.println("Time in mins: " + (now - then) / 60000d);
shapeList = separateShapeIntoRegions(area);
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
output.addMouseMotionListener(new MousePositionListener());
ui.add(output);
refresh();
}
public Area getOutline(Color target, BufferedImage bi, int tolerance) {
// construct the GeneralPath
GeneralPath gp = new GeneralPath();
boolean cont = false;
for (int xx = 0; xx < bi.getWidth(); xx++) {
for (int yy = 0; yy < bi.getHeight(); yy++) {
if (isIncluded(new Color(bi.getRGB(xx, yy)), target, tolerance)) {
//if (bi.getRGB(xx,yy)==targetRGB) {
if (cont) {
gp.lineTo(xx, yy);
gp.lineTo(xx, yy + 1);
gp.lineTo(xx + 1, yy + 1);
gp.lineTo(xx + 1, yy);
gp.lineTo(xx, yy);
} else {
gp.moveTo(xx, yy);
}
cont = true;
} else {
cont = false;
}
}
cont = false;
}
gp.closePath();
// construct the Area from the GP & return it
return new Area(gp);
}
public static ArrayList<Shape> separateShapeIntoRegions(Shape shape) {
ArrayList<Shape> regions = new ArrayList<>();
PathIterator pi = shape.getPathIterator(null);
GeneralPath gp = new GeneralPath();
while (!pi.isDone()) {
double[] coords = new double[6];
int pathSegmentType = pi.currentSegment(coords);
int windingRule = pi.getWindingRule();
gp.setWindingRule(windingRule);
if (pathSegmentType == PathIterator.SEG_MOVETO) {
gp = new GeneralPath();
gp.setWindingRule(windingRule);
gp.moveTo(coords[0], coords[1]);
} else if (pathSegmentType == PathIterator.SEG_LINETO) {
gp.lineTo(coords[0], coords[1]);
} else if (pathSegmentType == PathIterator.SEG_QUADTO) {
gp.quadTo(coords[0], coords[1], coords[2], coords[3]);
} else if (pathSegmentType == PathIterator.SEG_CUBICTO) {
gp.curveTo(
coords[0], coords[1],
coords[2], coords[3],
coords[4], coords[5]);
} else if (pathSegmentType == PathIterator.SEG_CLOSE) {
gp.closePath();
regions.add(new Area(gp));
} else {
System.err.println("Unexpected value! " + pathSegmentType);
}
pi.next();
}
return regions;
}
class MousePositionListener implements MouseMotionListener {
#Override
public void mouseDragged(MouseEvent e) {
// do nothing
}
#Override
public void mouseMoved(MouseEvent e) {
refresh();
}
}
public static boolean isIncluded(Color target, Color pixel, int tolerance) {
int rT = target.getRed();
int gT = target.getGreen();
int bT = target.getBlue();
int rP = pixel.getRed();
int gP = pixel.getGreen();
int bP = pixel.getBlue();
return ((rP - tolerance <= rT) && (rT <= rP + tolerance)
&& (gP - tolerance <= gT) && (gT <= gP + tolerance)
&& (bP - tolerance <= bT) && (bT <= bP + tolerance));
}
private void refresh() {
output.setIcon(new ImageIcon(getImage()));
}
private BufferedImage getImage() {
BufferedImage bi = new BufferedImage(
2 * SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
g.drawImage(image, 0, 0, output);
g.setColor(Color.ORANGE.darker());
g.fill(area);
g.setColor(Color.RED);
g.draw(area);
try {
Point p = MouseInfo.getPointerInfo().getLocation();
Point p1 = output.getLocationOnScreen();
int x = p.x - p1.x;
int y = p.y - p1.y;
Point pointOnImage = new Point(x, y);
for (Shape shape : shapeList) {
if (shape.contains(pointOnImage)) {
g.setColor(Color.GREEN.darker());
g.fill(shape);
break;
}
}
} catch (Exception doNothing) {
}
g.dispose();
return bi;
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
WorldMapArea o = new WorldMapArea();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.setResizable(false);
f.pack();
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}

Adding JMenubar to work for both Server-Client based TicTacToe game

I practiced Tic Tac Toe game from a video online. The game is working perfectly. I need to improvise it by providing JMenuBar in this way
JMenuBar > File > New && Exit
This is the Complete code:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class TicTacToeNewExit implements Runnable, ActionListener{
private String ip = "localhost";
private int port = 22222;
private Scanner scanner = new Scanner(System.in);
private JFrame frame;
private Painter painter;
private Thread thread;
private int WIDTH = 506;
private int HEIGHT = 547;
private JMenuBar jMenuBar;
private JMenu menu;
private JMenuItem newMenuItem, exitMenuItem;
private Socket socket;
private ServerSocket serverSocket;
private DataOutputStream dos;
private DataInputStream dis;
private boolean won = false;
private boolean enemyWon = false;
private boolean tie = false;
private boolean accepted = false;
private boolean circle = true;
private boolean unableToCommunicateWithOpponent = false;
private boolean yourTurn = false;
private BufferedImage board;
private BufferedImage redX;
private BufferedImage redCircle;
private BufferedImage blueX;
private BufferedImage blueCircle;
private String[] spaces = new String[9];
private int lengthOfSpace = 160;
private int errors = 0;
private int firstSpot = -1;
private int secondSpot = -1;
private String wonString = "You Won";
private String enemyWonString = "Opponent Won";
private String unableToCommunicateWithOpponentString = "Cannot connect to opponent";
private String tieString = "It's a tie";
private String waitingString = "Waiting for another player.";
private Font font = new Font("Verdana", Font.BOLD, 30);
private Font smallerFont = new Font("Verdana", Font.BOLD, 20);
private Font largerFont = new Font("Verdana", Font.BOLD, 40);
private int[][] wins = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
public TicTacToeNewExit(){
System.out.println("Enter IP: ");
ip = scanner.nextLine();
System.out.println("Enter port: ");
port = scanner.nextInt();
if(port<1025 || port>65523){
System.out.println("Port Range Problem. Re-enter: ");
port = scanner.nextInt();
}
loadImages();
painter = new Painter();
if(!connect()) initializeServer();
jMenuBar = new JMenuBar();
menu = new JMenu("File");
newMenuItem = new JMenuItem("New");
newMenuItem.setMnemonic(KeyEvent.VK_N);
newMenuItem.setActionCommand("New");
newMenuItem.addActionListener(this);
exitMenuItem = new JMenuItem("Exit");
exitMenuItem.setActionCommand("Exit");
exitMenuItem.addActionListener(this);
menu.add(newMenuItem);
menu.add(exitMenuItem);
jMenuBar.add(menu);
frame = new JFrame();
frame.setTitle("TicTacToePractice");
frame.setContentPane(painter);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setJMenuBar(jMenuBar);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
thread = new Thread(this, "TicTacToe1");
thread.start();
}
private void render(Graphics g){
g.drawImage(board, 0, 0, null);
if(unableToCommunicateWithOpponent){
g.setColor(Color.ORANGE);
g.setFont(smallerFont);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int stringWidth = g2.getFontMetrics().stringWidth(unableToCommunicateWithOpponentString);
g.drawString(unableToCommunicateWithOpponentString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
return;
}
if(accepted){
for (int i = 0; i < spaces.length; i++) {
if (spaces[i] != null) {
int x = (i % 3) * lengthOfSpace + 10 * (i % 3);
int y = (int) (i / 3) * lengthOfSpace + 10 * (int) (i / 3);
if (spaces[i].equals("X")) {
if (circle) {
g.drawImage(redX, x, y, null);
} else {
g.drawImage(blueX, x, y, null);
}
} else if (spaces[i].equals("O")) {
if (circle) {
g.drawImage(blueCircle, x, y, null);
} else {
g.drawImage(redCircle, x, y, null);
}
}
}
}
if (won || enemyWon) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(10));
g.setColor(Color.BLACK);
g.drawLine(firstSpot % 3 * lengthOfSpace + 10 * firstSpot % 3 + lengthOfSpace / 2,
(int) (firstSpot / 3) * lengthOfSpace + 10 * (int) (firstSpot / 3) + lengthOfSpace / 2,
secondSpot % 3 * lengthOfSpace + 10 * secondSpot % 3 + lengthOfSpace / 2,
(int) (secondSpot / 3) * lengthOfSpace + 10 * (int) (secondSpot / 3) + lengthOfSpace / 2); //(x1,y1) && (x2,y2)
g.setColor(Color.GREEN);
g.setFont(largerFont);
if (won) {
int stringWidth = g2.getFontMetrics().stringWidth(wonString);
g.drawString(wonString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
} else if (enemyWon) {
int stringWidth = g2.getFontMetrics().stringWidth(enemyWonString);
g.drawString(enemyWonString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
}
}
if (tie) {
Graphics2D g2 = (Graphics2D) g;
g.setColor(Color.BLACK);
g.setFont(largerFont);
int stringWidth = g2.getFontMetrics().stringWidth(tieString);
g.drawString(tieString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
}
}else{
g.setColor(Color.YELLOW);
g.setFont(font);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int stringWidth = g2.getFontMetrics().stringWidth(waitingString);
g.drawString(waitingString, WIDTH / 2 - stringWidth / 2, HEIGHT / 2);
return;
}
}
private void loadImages() {
try{
board = ImageIO.read(getClass().getResourceAsStream("/board.png"));
redX = ImageIO.read(getClass().getResourceAsStream("/redX.png"));
redCircle = ImageIO.read(getClass().getResourceAsStream("/redCircle.png"));
blueX = ImageIO.read(getClass().getResourceAsStream("/blueX.png"));
blueCircle = ImageIO.read(getClass().getResourceAsStream("/blueCircle.png"));
}catch(IOException e){
e.printStackTrace();
}
}
private boolean connect() {
try{
socket = new Socket(ip, port);
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
accepted = true;
}catch(IOException e){
System.out.println("Unable to connect to the server. So starting a server on own....Server Started");
return false;
}
System.out.println("Client Connected to Server....");
return true;
}
private void initializeServer() {
try{
serverSocket = new ServerSocket(port);
}catch(Exception e){
e.printStackTrace();
}
yourTurn = true;
circle = false;
}
#Override
public void run() {
while(true){
tick();
painter.repaint();
if(!circle && !accepted){
listenToServerRequest();
}
}
}
private void listenToServerRequest() {
Socket socket = null;
try{
socket = serverSocket.accept();
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
accepted = true;
System.out.println("Client has requested to join. We will accept");
}catch(IOException e){
e.printStackTrace();
}
}
private void tick() {
if(errors >= 10) System.out.println("Too many errors. Take a step down and get a life");
if(!yourTurn && !unableToCommunicateWithOpponent){
try{
int position = dis.readInt();
if(circle){
spaces[position] = "X";
}
else{
spaces[position] = "O";
}
checkForEnemyWin();
checkForTie();
yourTurn = true;
}catch(IOException e){
e.printStackTrace();
errors++;
}
}
}
private void checkForWin(){
for(int i = 0; i < wins.length; i++){
if(circle){
if(spaces[wins[i][0]]=="O" && spaces[wins[i][1]]=="O" && spaces[wins[i][2]]=="O"){
firstSpot = wins[i][0];
secondSpot = wins[i][2];
won = true;
}
}else{
if(spaces[wins[i][0]]=="X" && spaces[wins[i][1]]=="X" && spaces[wins[i][2]]=="X"){
firstSpot = wins[i][0];
secondSpot = wins[i][2];
won = true;
}
}
}
}
private void checkForEnemyWin(){
for (int i = 0; i < wins.length; i++) {
if (circle) {
if (spaces[wins[i][0]] == "X" && spaces[wins[i][1]] == "X" && spaces[wins[i][2]] == "X") {
firstSpot = wins[i][0];
secondSpot = wins[i][2];
enemyWon = true;
}
} else {
if (spaces[wins[i][0]] == "O" && spaces[wins[i][1]] == "O" && spaces[wins[i][2]] == "O") {
firstSpot = wins[i][0];
secondSpot = wins[i][2];
enemyWon = true;
}
}
}
}
private void checkForTie(){
for(int i = 0; i < spaces.length; i++){
if(spaces[i] == null){
return;
}
}
tie = true;
}
#SuppressWarnings("unused")
public static void main(String[] args) {
TicTacToeNewExit ticTacToe = new TicTacToeNewExit();
}
private class Painter extends JPanel implements MouseListener{
private static final long serialVersionUID = 1L;
public Painter(){
setFocusable(true);
requestFocus();
setBackground(Color.WHITE);
addMouseListener(this);
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
render(g);
}
#Override
public void mouseClicked(MouseEvent e) {
if(accepted){
if(yourTurn && !unableToCommunicateWithOpponent && !won && !enemyWon){
int x = e.getX()/lengthOfSpace;
int y = e.getY()/lengthOfSpace;
y *= 3;
int position = x+y;
if(spaces[position] == null){
if(!circle) spaces[position] = "X";
else spaces[position] = "O";
yourTurn = false;
repaint();
Toolkit.getDefaultToolkit().sync();
try{
dos.writeInt(position);
dos.flush();
}catch(IOException e1){
errors++;
e1.printStackTrace();
}
System.out.println("Data was sent");
checkForWin();
checkForTie();
}
}
}
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
#Override
public void actionPerformed(ActionEvent a) {
if(a.getSource() == this.newMenuItem){
this.frame.setContentPane(painter);
errors = 0;
//new TicTacToeNewExit();
}
if(a.getSource() == this.exitMenuItem){
System.exit(0);
}
}
}
ActionPerformed is at the very bottom of the code.
I am unable to repaint() the whole server side and client side game using new. Instead the GUI closes and again asks for localhost and port number. How should I proceed in such a way that:
if "new" were clicked from either side, a dialogue box would appear on the other side asking the user if they would like to continue for a new game. If "yes", then instead of writing the localhost and port again, it should just refresh the "painter" and start a new game.
if "exit" were clicked from either side, a dialogue box would appear on other side displaying that the opponent player has exited.

DrawImage gone when off screen

Recently I have been building an application that draws images on a JFrame, everything is great, but when the window goes off screen, the images that have been drawn have disappeared, and I have been wondering if there is a way to avoid that? Thanks
import javax.swing.*;
import java.awt.;
import java.awt.event.;
public class Pokemoneur extends JFrame implements AdjustmentListener,
ActionListener, MouseListener, Runnable {
private JButton a = new JButton("Reset");
private int nbi = 7;
private JPanel frame;
private int n;
private int x2, y2;
private static int temp2;
private Object src;
private Thread t;
private JButton[] v = new JButton[nbi];
private ImageIcon[] imagei = new ImageIcon[7];
private JPanel canevas = new JPanel();
private JTextField nombre = new JTextField(7);
private JScrollBar js = new JScrollBar(0, 0, 0, 0, 100);
private JPanel panboutton = new JPanel(new GridLayout(1, 8));
private JPanel panjs = new JPanel(new BorderLayout(5, 5));
private JPanel frame2 = new JPanel(new GridLayout(2, 1, 5, 5));
private Graphics g;
public Pokemoneur() {
startGUI();
list();
this.setVisible(true);
}
public void startGUI() {
int max = 1000;
frame = (JPanel) this.getContentPane();
for (int i = 0; i < imagei.length; i++) {
}
frame.add(canevas);
frame.add(frame2, "North");
frame2.add(panboutton);
frame2.add(panjs);
js.setValue(6);
nombre.setText("" + js.getValue());
for (int i = 0; i < nbi; i++) {
imagei[i] = new ImageIcon(getClass()
.getResource("pok" + i + ".png"));
v[i] = new JButton(imagei[i]);
panboutton.add(v[i]);
}
panjs.add(js);
js.setMaximum(max);
panjs.add(nombre, "East");
frame.setPreferredSize(new Dimension(500, 500));
frame.setBorder(BorderFactory.createTitledBorder("Marc André 2014"));
panjs.setBorder(BorderFactory.createTitledBorder("Numbers of Pokemons"));
canevas.setBorder(BorderFactory.createTitledBorder("Party"));
frame.add(a, "South");
g = canevas.getGraphics();
this.pack();
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void run() {
for (int i = 0; i < v.length; i++) {
if (src == v[i]) {
for (int j = 0; j < js.getValue(); j++) {
int x = (int) (Math.random() * canevas.getWidth());
int y = (int) (Math.random() * canevas.getHeight());
int n = 0;
do {
n = (int) (Math.random() * nbi);
} while (n == i);
if (x > 80)
x -= 80;
if (y > 80)
y -= 80;
g.drawImage(imagei[n].getImage(), x, y, null);
}
x2 = (int) (Math.random() * canevas.getWidth());
y2 = (int) (Math.random() * canevas.getHeight());
if (x2 > 80)
x2 -= 80;
if (y2 > 80)
y2 -= 80;
g.drawImage(imagei[i].getImage(), x2, y2, null);
temp2 = i;
do {
n = (int) (Math.random() * nbi);
} while (n == temp2);
g.drawImage(imagei[n].getImage(), x2 + 13, y2, null);
}
}
}
public void list() {
js.addAdjustmentListener(this);
for (int i = 0; i < nbi; i++) {
v[i].addActionListener(this);
}
a.addActionListener(this);
canevas.addMouseListener(this);
}
public void adjustmentValueChanged(AdjustmentEvent x) {
nombre.setText("" + js.getValue());
}
public void actionPerformed(ActionEvent ae) {
src = ae.getSource();
if (src == a) {
try {
g.setColor(canevas.getBackground());
g.fillRect(0, 0, canevas.getWidth(), canevas.getHeight());
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
g = canevas.getGraphics();
g.setColor(canevas.getBackground());
g.fillRect(0, 0, canevas.getWidth(), canevas.getHeight());
t = new Thread(this);
t.start();
}
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
System.out.println(x2 + "," + y2 + "\n" + x + " " + y);
// if((x>=x2 && x<=x2+80)&&(x>=x2 && y<=y2+80)){
if ((x >= x2 && x <= x2 + 80) && (y >= y2 && y <= y2 + 80)) {
System.out.println("True");
g.setColor(canevas.getBackground());
g.fillRect(0, 0, canevas.getWidth(), canevas.getHeight());
System.out.println("in");
g.drawImage(imagei[temp2].getImage(), x2, y2, null);
System.out.println(temp2);
System.out.println("end");
} else {
System.out.println("false");
}
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
new Pokemoneur();
}
}
The problem is that when the user move the Jframe when the images have been drawn off the screen, the image don't stay...
Before: http://i.stack.imgur.com/KHIvm.png
After : http://i.stack.imgur.com/koZSI.png
You ask:
but when the window goes off screen, the images that have been drawn have disappeared, and I have been wondering if there is a way to avoid that?
This means that you have a bug in your code somewhere, in code that you're not in fact showing us.
Perhaps you're drawing with a Graphics object that you've obtained by calling getGraphics() on a component, but all I can do is make a wild A$$ed guess at this point. If you are doing this, don't. Calling getGraphics() on a component will get you a Graphics object that will not persist on repeat paints, and will result in images that likewise don't persist. Draw instead in the paintComponent(Graphics g) method of a JPanel that is displayed in the JFrame as is well described in the Performing Custom Painting with Swing tutorials. But most important, please put just a little effort into asking your question so we don't have to guess at code not seen.

Why doesn't my code uses default non parameterized constructor, if one constructor with parameters is defined?

Okay so, I've my main class which loads everything in from my framework. What I'm having trouble with now is my collision detection; I've got it so if it hits something, something will happen. I've a method that calls a GameOverUI in the GameScreen class, but I want to use that in my Enemy.class .. I've created a new instance for the object but it's saying its undefined. What I dont get is the class has no definition but a method called GameScreen is defined by (Game game).
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import android.graphics.Color;
import android.graphics.Paint;
import com.vaughanslater.framework.Game;
import com.vaughanslater.framework.Graphics;
import com.vaughanslater.framework.Image;
import com.vaughanslater.framework.Input.TouchEvent;
import com.vaughanslater.framework.Screen;
public class GameScreen extends Screen {
enum GameState {
Ready, Running, Paused, GameOver
}
GameState state = GameState.Ready;
// Variable Setup
private static Background bg1, bg2;
private static Robot robot;
public static Heliboy hb, hb2;
private Image currentSprite, character, character2, character3, heliboy,
heliboy2, heliboy3, heliboy4, heliboy5;
private Animation anim, hanim;
private ArrayList tilearray = new ArrayList();
int livesLeft = 1;
Paint paint, paint2;
public GameScreen(Game game) {
super(game);
// Initialize game objects here
bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);
robot = new Robot();
hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);
character = Assets.character;
character2 = Assets.character2;
character3 = Assets.character3;
heliboy = Assets.heliboy;
heliboy2 = Assets.heliboy2;
heliboy3 = Assets.heliboy3;
heliboy4 = Assets.heliboy4;
heliboy5 = Assets.heliboy5;
anim = new Animation();
anim.addFrame(character, 1250);
anim.addFrame(character2, 50);
anim.addFrame(character3, 50);
anim.addFrame(character2, 50);
hanim = new Animation();
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy2, 100);
currentSprite = anim.getImage();
loadMap();
// Defining a paint object
paint = new Paint();
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint2 = new Paint();
paint2.setTextSize(100);
paint2.setTextAlign(Paint.Align.CENTER);
paint2.setAntiAlias(true);
paint2.setColor(Color.WHITE);
}
private void loadMap() {
ArrayList lines = new ArrayList();
int width = 0;
int height = 0;
Scanner scanner = new Scanner(SampleGame.map);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
// no more lines to read
if (line == null) {
break;
}
if (!line.startsWith("!")) {
lines.add(line);
width = Math.max(width, line.length());
}
}
height = lines.size();
for (int j = 0; j < 12; j++) {
String line = (String) lines.get(j);
for (int i = 0; i < width; i++) {
if (i < line.length()) {
char ch = line.charAt(i);
Tile t = new Tile(i, j, Character.getNumericValue(ch));
tilearray.add(t);
}
}
}
}
#Override
public void update(float deltaTime) {
List touchEvents = game.getInput().getTouchEvents();
// We have four separate update methods in this example.
// Depending on the state of the game, we call different update methods.
// Refer to Unit 3's code. We did a similar thing without separating the
// update methods.
if (state == GameState.Ready)
updateReady(touchEvents);
if (state == GameState.Running)
updateRunning(touchEvents, deltaTime);
if (state == GameState.Paused)
updatePaused(touchEvents);
if (state == GameState.GameOver)
updateGameOver(touchEvents);
}
private void updateReady(List touchEvents) {
// This example starts with a "Ready" screen.
// When the user touches the screen, the game begins.
// state now becomes GameState.Running.
// Now the updateRunning() method will be called!
if (touchEvents.size() > 0)
state = GameState.Running;
}
private void updateRunning(List touchEvents, float deltaTime) {
// This is identical to the update() method from our Unit 2/3 game.
// 1. All touch input is handled here:
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = (TouchEvent) touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN) {
if (event.x > 400) {
robot.jump();
currentSprite = anim.getImage();
robot.setDucked(false);
}
else if (inBounds(event, 0, 350, 65, 65)) {
if (robot.isDucked() == false && robot.isJumped() == false
&& robot.isReadyToFire()) {
robot.shoot();
}
}
else if (event.x < 400
&& robot.isJumped() == false) {
currentSprite = Assets.characterDown;
robot.setDucked(true);
robot.setSpeedX(0);
}
//if (event.x > 400) {
// Move right.
// robot.moveRight();
// robot.setMovingRight(true);
//}
}
if (event.type == TouchEvent.TOUCH_UP) {
if (event.x < 400) {
currentSprite = anim.getImage();
robot.setDucked(false);
}
if (inBounds(event, 0, 0, 35, 35)) {
pause();
}
if (event.x > 400) {
// Move right.
robot.stopRight();
}
}
}
// 2. Check miscellaneous events like death:
if (livesLeft == 0) {
state = GameState.GameOver;
}
// 3. Call individual update() methods here.
// This is where all the game updates happen.
// For example, robot.update();
robot.update();
if (robot.isJumped()) {
currentSprite = Assets.characterJump;
} else if (robot.isJumped() == false && robot.isDucked() == false) {
currentSprite = anim.getImage();
}
ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
if (p.isVisible() == true) {
p.update();
} else {
projectiles.remove(i);
}
}
updateTiles();
hb.update();
hb2.update();
bg1.update();
bg2.update();
animate();
if (robot.getCenterY() > 500) {
state = GameState.GameOver;
}
}
private boolean inBounds(TouchEvent event, int x, int y, int width,
int height) {
if (event.x > x && event.x < x + width - 1 && event.y > y
&& event.y < y + height - 1)
return true;
else
return false;
}
private void updatePaused(List touchEvents) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = (TouchEvent) touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_UP) {
if (inBounds(event, 0, 0, 800, 240)) {
if (!inBounds(event, 0, 0, 35, 35)) {
resume();
}
}
if (inBounds(event, 0, 240, 800, 240)) {
nullify();
goToMenu();
}
}
}
}
private void updateGameOver(List touchEvents) {
int len = touchEvents.size();
for (int i = 0; i < len; i++) {
TouchEvent event = (TouchEvent) touchEvents.get(i);
if (event.type == TouchEvent.TOUCH_DOWN) {
if (inBounds(event, 0, 0, 800, 480)) {
nullify();
game.setScreen(new MainMenuScreen(game));
return;
}
}
}
}
private void updateTiles() {
for (int i = 0; i < tilearray.size(); i++) {
Tile t = (Tile) tilearray.get(i);
t.update();
}
}
#Override
public void paint(float deltaTime) {
Graphics g = game.getGraphics();
g.drawImage(Assets.background, bg1.getBgX(), bg1.getBgY());
g.drawImage(Assets.background, bg2.getBgX(), bg2.getBgY());
paintTiles(g);
ArrayList projectiles = robot.getProjectiles();
for (int i = 0; i < projectiles.size(); i++) {
Projectile p = (Projectile) projectiles.get(i);
g.drawRect(p.getX(), p.getY(), 10, 5, Color.YELLOW);
}
// First draw the game elements.
g.drawImage(currentSprite, robot.getCenterX() - -15,
robot.getCenterY() - -17);
g.drawImage(hanim.getImage(), hb.getCenterX() - 48,
hb.getCenterY() - 48);
g.drawImage(hanim.getImage(), hb2.getCenterX() - 48,
hb2.getCenterY() - 48);
// Example:
// g.drawImage(Assets.background, 0, 0);
// g.drawImage(Assets.character, characterX, characterY);
// Secondly, draw the UI above the game elements.
if (state == GameState.Ready)
drawReadyUI();
if (state == GameState.Running)
drawRunningUI();
if (state == GameState.Paused)
drawPausedUI();
if (state == GameState.GameOver)
drawGameOverUI();
}
private void paintTiles(Graphics g) {
for (int i = 0; i < tilearray.size(); i++) {
Tile t = (Tile) tilearray.get(i);
if (t.type != 0) {
g.drawImage(t.getTileImage(), t.getTileX(), t.getTileY());
}
}
}
public void animate() {
anim.update(10);
hanim.update(50);
}
private void nullify() {
// Set all variables to null. You will be recreating them in the
// constructor.
paint = null;
bg1 = null;
bg2 = null;
robot = null;
hb = null;
hb2 = null;
currentSprite = null;
character = null;
character2 = null;
character3 = null;
heliboy = null;
heliboy2 = null;
heliboy3 = null;
heliboy4 = null;
heliboy5 = null;
anim = null;
hanim = null;
// Call garbage collector to clean up memory.
System.gc();
}
private void drawReadyUI() {
Graphics g = game.getGraphics();
g.drawARGB(155, 0, 0, 0);
g.drawString("Tap to Start.", 400, 240, paint);
}
private void drawRunningUI() {
Graphics g = game.getGraphics();
//g.drawImage(Assets.button, 0, 285, 0, 0, 65, 65);
//g.drawImage(Assets.button, 0, 350, 0, 65, 65, 65);
//g.drawImage(Assets.button, 0, 415, 0, 130, 65, 65);
g.drawImage(Assets.button, 0, 0, 0, 195, 35, 35);
}
private void drawPausedUI() {
Graphics g = game.getGraphics();
// Darken the entire screen so you can display the Paused screen.
g.drawARGB(155, 0, 0, 0);
g.drawString("Resume", 400, 165, paint2);
g.drawString("Menu", 400, 360, paint2);
}
public void drawGameOverUI() {
Graphics g = game.getGraphics();
g.drawRect(0, 0, 1281, 801, Color.BLACK);
g.drawString("GAME OVER.", 400, 240, paint2);
g.drawString("Tap to return.", 400, 290, paint);
}
#Override
public void pause() {
if (state == GameState.Running)
state = GameState.Paused;
}
#Override
public void resume() {
if (state == GameState.Paused)
state = GameState.Running;
}
public GameState getState() {
return state;
}
public void setState(GameState state) {
this.state = state;
}
#Override
public void dispose() {
}
#Override
public void backButton() {
pause();
}
private void goToMenu() {
// TODO Auto-generated method stub
game.setScreen(new MainMenuScreen(game));
}
public static Background getBg1() {
// TODO Auto-generated method stub
return bg1;
}
public static Background getBg2() {
// TODO Auto-generated method stub
return bg2;
}
public static Robot getRobot() {
// TODO Auto-generated method stub
return robot;
}
}
Heres my enemy class too:
import android.graphics.Rect;
public class Enemy {
private int power, centerX, speedX, centerY;
private Background bg = GameScreen.getBg1();
private Robot robot = GameScreen.getRobot();
public Rect r = new Rect(0, 0, 0, 0);
public int health = 5;
private int movementSpeed;
// Behavioural Methods
public void update() {
follow();
centerX += speedX;
speedX = bg.getSpeedX() * 5 + movementSpeed;
r.set(centerX - 25, centerY - 25, centerX + 25, centerY + 35);
if (Rect.intersects(r, Robot.yellowRed)) {
checkCollision();
}
}
private void checkCollision() {
if (Rect.intersects(r, Robot.rect) || Rect.intersects(r, Robot.rect2)
|| Rect.intersects(r, Robot.rect3)
|| Rect.intersects(r, Robot.rect4)) {
GameScreen state = new GameScreen(); // This is where it errors
}
}
public void follow() {
if (centerX < -95 || centerX > 810) {
movementSpeed = 0;
}
else if (Math.abs(robot.getCenterX() - centerX) < 5) {
movementSpeed = 0;
}
else {
if (robot.getCenterX() >= centerX) {
movementSpeed = 1;
} else {
movementSpeed = -1;
}
}
}
public void die() {
}
public void attack() {
}
public int getPower() {
return power;
}
public int getSpeedX() {
return speedX;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public Background getBg() {
return bg;
}
public void setPower(int power) {
this.power = power;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setBg(Background bg) {
this.bg = bg;
}
}
So here is where it errors:
GameScreen state = new GameScreen(); // This is where it errors
I dont get it, I'm not calling the method GameScreen(Game game) which is defined, but I'm calling the class which isn't. I want to use the drawGameOverUI();.
Sorry for the wall of code.. atleast you can see everthing.
If you define any constructor , default constructor is never used. Please define implementation of GameScreen() or remove the implementation of GameScreen(Game game).
Define a default constructor like this -
public GameScreen() {
super();
// Initialize game objects here
bg1 = new Background(0, 0);
bg2 = new Background(2160, 0);
robot = new Robot();
hb = new Heliboy(340, 360);
hb2 = new Heliboy(700, 360);
character = Assets.character;
character2 = Assets.character2;
character3 = Assets.character3;
heliboy = Assets.heliboy;
heliboy2 = Assets.heliboy2;
heliboy3 = Assets.heliboy3;
heliboy4 = Assets.heliboy4;
heliboy5 = Assets.heliboy5;
anim = new Animation();
anim.addFrame(character, 1250);
anim.addFrame(character2, 50);
anim.addFrame(character3, 50);
anim.addFrame(character2, 50);
hanim = new Animation();
hanim.addFrame(heliboy, 100);
hanim.addFrame(heliboy2, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy5, 100);
hanim.addFrame(heliboy4, 100);
hanim.addFrame(heliboy3, 100);
hanim.addFrame(heliboy2, 100);
currentSprite = anim.getImage();
loadMap();
// Defining a paint object
paint = new Paint();
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint2 = new Paint();
paint2.setTextSize(100);
paint2.setTextAlign(Paint.Align.CENTER);
paint2.setAntiAlias(true);
paint2.setColor(Color.WHITE);
}
By defining a constructor that accepts an argument you are forcing users to call it.
If you want one without a mandatory game param, define one.

Three Paddle Pong Hit Detection

I am creating yet another version of pong. This one uses 3 paddles for each person. I have spent almost two hours trying to figure out why the two other paddles are not detecting when the ball strikes the paddle. The original (top) paddle does detect the hit and properly updates the hit counter. I have tried separate if statements, else if statements etc., with no success. I created three Y variables to detect the position of all three paddles still no luck.
Any suggestions?
import java.awt.Point;
public class box {
private int xTopLeft, yTopLeft, width, height;
int xBall, yBall;
private int radius = 5;
int xBallVel, yBallVel;
int VELOCITY_MAG =5;
public Point ballLoc = new Point();
private int paddleY;
private int paddleYP2;
private int paddleYP3;
private int paddleWidth = 20;
private int paddleWidth2 = 20;
private int paddleWidth3 = 20;
int hitCount = 0;
int missCount = 0;
private boolean updating=true;
public int getBallRadius()
{
return radius;
}
public Point getBallLoc()
{
ballLoc.x = xBall;
ballLoc.y = yBall;
return ballLoc;
}
public box(int x, int y, int w, int h)
{
xTopLeft =x;
yTopLeft = y;
width =w;
height = h;
createRandomBallLocation();
}
public void updatePaddle(int y)
{
paddleY = y;
}
public void updatePaddleP2(int yp2)
{
paddleYP2 = yp2;
}
public void updatePaddleP3(int yp3)
{
paddleYP3 = yp3;
}
public int getPaddleWidth()
{
return paddleWidth ;
}
public int getPaddleWidth2()
{
return paddleWidth2 ;
}
public int getPaddleWidth3()
{
return paddleWidth3 ;
}
public int getPaddleY()
{
System.out.println(paddleY);
return paddleY;
}
public int getPaddleP2()
{
System.out.println(paddleYP2);
return paddleYP2;
}
public int getPaddleP3()
{
return paddleYP3;
}
public int getHitCount()
{
return hitCount;
}
public int getMissCount()
{
return missCount;
}
public int velMag()
{
return VELOCITY_MAG;
}
public void update()
{
if (!updating) return;
xBall = xBall + xBallVel;
yBall = yBall + yBallVel;
if (xBall + radius >= xTopLeft+width && xBallVel>=0)
if ((yBall >= paddleY-paddleWidth && yBall <= paddleY + paddleWidth)
|| (yBall >= paddleYP2-paddleWidth2 && yBall <= paddleYP2 + paddleWidth2 )
|| (yBall >= paddleYP3-paddleWidth3 && yBall <= paddleYP3 + paddleWidth3 ))
{
// hit paddles
xBallVel = - xBallVel;
hitCount++;
}
else if (xBall+radius >= xTopLeft + width)
{
xBallVel = - xBallVel;
}
if (yBall+radius >= yTopLeft + height && yBallVel >= 0)
{
yBallVel = - yBallVel;
}
if (yBall-radius <= yTopLeft && yBallVel <=0)
{
yBallVel = - yBallVel;
}
if (xBall-radius <= xTopLeft && xBallVel <= 0)
{
xBallVel = - xBallVel;
}
}
public void createRandomBallLocation()
{
xBall = xTopLeft + radius +
(int)((width-2*radius)*Math.random());
yBall = yTopLeft + radius +
(int)((height-2*radius)*Math.random());
xBallVel = velMag();
yBallVel = velMag();
}
}
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
public class Pong extends JFrame
implements Runnable{
box box = null;
int top, left, width, height;
final int LINE_THICKNESS = 5;
Graphics bufferGraphics;
int sleep=25;
public Pong(String name)
{
super(name);
int windowWidth = 1024;
int windowHeight =768;
this.setSize(windowWidth, windowHeight);
this.setResizable(false);
this.setLocation(400, 150);
this.setVisible(true);
this.createBufferStrategy(4);
MyMouseClick mmc = new MyMouseClick();
addMouseListener(mmc);
MyMouseMotion mmm = new MyMouseMotion();
addMouseMotionListener(mmm);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Thread thread = new Thread(this);
thread.start();
}
public void run()
{
while(true)
{
try
{
if (box != null)
{
box.update();
repaint();
}
Thread.sleep(sleep);
}
catch (InterruptedException e)
{}
}
}
public void paint(Graphics g)
{
BufferStrategy bf = this.getBufferStrategy();
g = bf.getDrawGraphics();
Dimension d = getSize();
if (box ==null)
{
Insets insets = getInsets();
left = insets.left;
top = insets.top;
width = d.width-left - insets.right;
height = d.height - top - insets.bottom;
box = new box(left, top, width, height);
}
g.fillRect(0,0, d.width, d.height);
g.setColor(Color.BLUE);
g.setFont(new Font("Arial", 20, 30));
g.drawString("Hits: "+box.getHitCount(), 20, 60);
g.setColor(Color.red);
g.setFont(new Font("Arial", 20, 30));
g.drawString("Misses: "+box.getMissCount(), 20, 380);
g.fillRect(left, top, left+width, LINE_THICKNESS); // top of box
g.setColor(Color.white);
g.fillRect(left, top+height, left+width, LINE_THICKNESS); // bottom of box
g.drawLine(left, top, left, top+height); // left of box
g.drawLine(left+width, top, left+width, top+height); // right side
Point ballLoc = box.getBallLoc();
int radius = box.getBallRadius();
g.fillOval(ballLoc.x - radius, ballLoc.y-radius, 2*radius, 2*radius);
// Draw paddles Player 1
g.setColor(Color.yellow);
int yp = box.getPaddleY();
int yp2 = box.getPaddleP2();
int yp3 = box.getPaddleP3();
int yw = box.getPaddleWidth();
int yw2 = box.getPaddleWidth2();
int yw3 = box.getPaddleWidth3();
g.fillRect(left+width-5, yp-yw, 4, 50);
g.fillRect(left+width-5, (yp2-yw2)+280, 4, 50);
g.fillRect(left+width-5, (yp3-yw3)+140, 4, 50);
bf.show();
}
// *********************** Inner classes
class MyMouseClick extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
box = null;
repaint();
}
}
class MyMouseMotion extends MouseMotionAdapter
{
public void mouseMoved(MouseEvent e)
{
int y = e.getY();
int y2 = e.getY();
int y3 = e.getY();
if (box != null)
{
box.updatePaddle(y);
box.updatePaddleP2(y2);
box.updatePaddleP3(y3);
repaint();
}
}
}
// ************************************
public static void main(String[] args) {
Pong t = new Pong("Three Paddle Pong");
t.setVisible(true);
} // end of main
}
In the paint method you do paint your 3 paddles at different y positions, but for the actual paddle positions, paddleYP? which are used for collision detection, you just set the 3 paddles to the same y in mouseMoved.

Categories