DrawImage gone when off screen - java

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.

Related

Prevent a component from being added to a jpanel if another component is already in place

So I am in the process of creating a game similar to Plants vs Zombies, however I've run into a slight problem: before I can apply the finishing touches such as levels, I need to prevent more than one JLabel being added to a JPanel. The placing of the JLabel works fine, though I think that I may have gone a roundabout route. The problem as stated above is that another JLabel can currently be added below a pre-existing JLabel. How do I set a JPanel to accept no more than the original component (the initial JLabel)? Any assistance would be greatly appreciated.
private final JFrame FRAME;
private final JPanel squares[][] = new JPanel[8][11];
private final Color DGY = Color.DARK_GRAY;
private final Color GRN = Color.GREEN;
private final Color BLK = Color.BLACK;
private final Color LGY = Color.LIGHT_GRAY;
private final Color GRY = Color.GRAY;
private final Color BLU = Color.BLUE;
private final Font F1 = new Font("Tahoma", 1, 36);
private String icon = "";
private int lvl = 10;
private void squareGen(int i, int j, Color col, boolean border)
{
squares[i][j].setBackground(col);
if (border)
{
squares[i][j].setBorder(BorderFactory.createLineBorder(BLK, 1));
}
FRAME.add(squares[i][j]);
}
public GameGUI()
{
FRAME = new JFrame("ESKOM VS SA");
FRAME.setSize(1600, 900);
FRAME.setLayout(new GridLayout(8, 11));
for (int x = 0; x < 8; x++)
{
if (x > 1 && x < 7)
{
squares[x][0] = new JPanel();
squareGen(x, 0, GRN, true);
} else if (x == 1 || x == 7)
{
squares[x][0] = new JPanel();
squareGen(x, 0, DGY, true);
} else
{
squares[x][0] = new JPanel();
squareGen(x, 0, BLU, false);
}
for (int y = 1; y < 11; y++)
{
squares[x][y] = new JPanel();
if (x == 0)
{
squareGen(x, y, BLU, false);
} else if (y == 10 || x == 1 || x == 7)
{
squareGen(x, y, DGY, true);
} else
{
squareGen(x, y, LGY, true);
addDToPanel(x, y);
}
}
}
JButton btnPause = new JButton();
btnPause.setText("||");
btnPause.setFont(F1);
btnPause.addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnPauseActionPerformed(evt);
}
});
squares[7][10].add(btnPause);
addButtons(8);
FRAME.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
FRAME.setLocationRelativeTo(null);
}
public void restart()
{
FRAME.dispose();
GameGUI ggui = new GameGUI();
ggui.setVisible(true);
}
public void mainMenu()
{
FRAME.dispose();
new StartUpUI().setVisible(true);
}
private void btnPauseActionPerformed(java.awt.event.ActionEvent evt)
{
new PauseGUI(this).setVisible(true);
}
private void btnAddDefenseActionPerformed(java.awt.event.ActionEvent evt)
{
JButton btn = (JButton) evt.getSource();
icon = btn.getActionCommand();
}
private void addButtons(int x)
{
JButton[] btn = new JButton[x];
for (int j = 1; j <= x; j++)
{
btn[j - 1] = new JButton();
ImageIcon ii = new ImageIcon(this.getClass().getResource("" + j + ".png"));
btn[j - 1].setIcon(ii);
btn[j - 1].setActionCommand("" + j);
btn[j - 1].setText("");
btn[j - 1].setForeground(btn[j - 1].getBackground());
squares[0][j].add(btn[j - 1]);
btn[j - 1].addActionListener(new java.awt.event.ActionListener()
{
#Override
public void actionPerformed(java.awt.event.ActionEvent evt)
{
btnAddDefenseActionPerformed(evt);
}
});
}
}
private void addDToPanel(int x, int y)
{
squares[x][y].addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent me)
{
JPanel panel = (JPanel) me.getSource();
int j = (int) (panel.getX() / 145.45454545) + 1;
int i = (int) (panel.getY() / 112.5) + 1;
addDefense(i, j, icon);
icon = "";
FRAME.revalidate();
FRAME.repaint();
}
});
}
private void addDefense(int i, int j, String imageName)
{
try
{
JLabel jlbl = new JLabel();
ImageIcon ii = new ImageIcon(this.getClass().getResource(imageName + ".png"));
jlbl.setIcon(ii);
squares[i][j].add(jlbl, java.awt.BorderLayout.CENTER);
} catch (Exception e)
{
}
}
public void setLvl(int lvl)
{
this.lvl = lvl;
}
public void setVisible(boolean b)
{
FRAME.setVisible(b);
}
This is not my main class, this class is instantiated in the main class and setVisible() = true;
Again thanks in advance!
How do I set a JPanel to accept no more than the original
You can use the Container.getComponentCount() method to check how many components have been added to the panel.
Only add your component when the count is 0.

MouseListener in Canvas not working

I am having a problem with a game that I am trying to make in Java. I am trying to attach a MouseListener to my canvas, however, when I click on the canvas, nothing happens. I think I may be attaching the MouseListener to the wrong thing, but I don't know what to attach it to. I have tried attaching it to the JFrame and the canvas. Here is my code:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.util.Random;
public class Gravity extends Canvas {
public static final int screenw = 1024;
public static final int screenh = 768;
public static Random gen = new Random();
public static Boolean started = false;
public static int[] starx = new int[100];
public static int[] stary = new int[100];
public static Color[] starc = new Color[100];
public static JFrame frame;
public static Gravity canvas;
public static Image buffer;
public static Graphics bg;
public static int[] xh = new int[1000];
public static int[] yh = new int[1000];
public static int i = 0;
public static Image title;
public static ArrayList<Integer> ptx = new ArrayList<Integer>();
public static ArrayList<Integer> pty = new ArrayList<Integer>();
double x = 100;
double y = 100;
public Gravity(){
}
public void paint (Graphics g) {
frame.addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent e){
started = true;
System.out.println("Mouse was clicked");
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
});
buffer = createImage(screenw, screenh);
bg = buffer.getGraphics();
int w = getWidth();
int h = getHeight();
double px = getWidth()/2;
double py = getHeight()/2;
bg.setColor(Color.BLACK);
bg.fillRect(0, 0, w, h); //black background
for (int j=0; j < 100; j++){ //make stars
starx[j] = gen.nextInt(w);
stary[j] = gen.nextInt(h);
starc[j] = new Color(gen.nextInt(100)+156, gen.nextInt(100)+156, gen.nextInt(100)+156);
bg.setColor(starc[j]);
bg.drawLine(starx[j], stary[j], starx[j]+2, stary[j]+2);
bg.drawLine(starx[j], stary[j]+2, starx[j]+2, stary[j]);
}
try {
title = ImageIO.read(new ByteArrayInputStream(Base64.decode(""))); //I have omitted the Base64 code for the image for my title screen
} catch (IOException e) {
e.printStackTrace();
}
bg.drawImage(title, 100, 100, null);
g.drawImage(buffer, 0, 0, null);
while (!started){
try {
Thread.sleep(50);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
double xvel = -15;
double yvel = 10;
for (int j=0; j < 100; j++){ //store stars
starx[j] = gen.nextInt(w);
stary[j] = gen.nextInt(h);
starc[j] = new Color(gen.nextInt(100)+156, gen.nextInt(100)+156, gen.nextInt(100)+156);
}
Image test = createImage(200,200);
Graphics testg = test.getGraphics();
testg.drawLine(50,50,150,150);
while(true){
g.drawImage(buffer, 0,0, null);
try {
Thread.sleep(33);
} catch (Exception e) {
e.printStackTrace();
}
bg.setColor(Color.BLACK);
bg.fillRect(0, 0, w, h); //black background
for (int j=0; j < 100; j++){ //draw stars
bg.setColor(starc[j]);
bg.drawLine(starx[j], stary[j], starx[j]+2, stary[j]+2);
bg.drawLine(starx[j], stary[j]+2, starx[j]+2, stary[j]);
}
bg.setColor(Color.BLUE);
if (i > 0){
for (int z=0; z < i-1; z++){
bg.drawLine(ptx.get(z), pty.get(z), ptx.get(z+1), pty.get(z+1));
}
}
bg.setColor(Color.CYAN);
bg.fillOval((int)px, (int)py, 25, 25); //planet
bg.setColor(Color.RED);
bg.fillRect((int)(x-5),(int)(y-5),10,10); //ship
double fg = (5*50000)/(Math.pow(dist(x,y,px,py),2));
double m = (y-py)/(x-px);
double ms = Math.sqrt(Math.abs(m));
if (m < 0) ms = -ms;
double xchg = fg;
double ychg = fg*ms;
if (x > px){
xchg = -xchg;
ychg = -ychg;
}
xvel += xchg;
yvel += ychg;
x += xvel;
y += yvel;
ptx.add((int)x);
pty.add((int)y);
i++;
}
}
public static void main(String[] args){
canvas = new Gravity();
frame = new JFrame();
frame.setSize(screenw, screenh);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(canvas);
frame.setVisible(true);
}
public static double dist(double x1, double y1, double x2, double y2){
double x = x2-x1;
double y = y2-y1;
return Math.sqrt((x*x)+(y*y));
}
}
General tips, in point form:
Don't mix AWT (e.g. Canvas) with Swing (e.g. JFrame) components. Instead of the Canvas, use a JPanel and override paintComponent(Graphics) rather than paint(Graphics).
Don't call Thread.sleep(n) on the EDT. Instead use a Swing based Timer to call repaint()
Don't perform long running operations on the paint method, especially starting an infinite loop! Even the creation of the buffer image should only be done in the case the screen size changes. (left as 'TODO' - BNI)
Add the MouseListener once in the constructor or an init() method rather than every time paint is called.
Highly recommend all of Nate's numbered list of notes.
Try this code, and compare it carefully to the original to see the changes.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Dimension;
import java.awt.event.*;
import java.util.ArrayList;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.util.Random;
public class Gravity extends JPanel {
public static final int screenw = 800;
public static final int screenh = 600;
public static Random gen = new Random();
public static int[] starx = new int[100];
public static int[] stary = new int[100];
public static Color[] starc = new Color[100];
public static Image buffer;
public static Graphics bg;
public static int[] xh = new int[1000];
public static int[] yh = new int[1000];
public static int i = 0;
public static ArrayList<Integer> ptx = new ArrayList<Integer>();
public static ArrayList<Integer> pty = new ArrayList<Integer>();
double x = 100;
double y = 100;
Timer timer;
public Gravity(){
// set thre PREFERRED size!
setPreferredSize(new Dimension(screenw, screenh));
addMouseListener(new MouseListener(){
public void mouseClicked(MouseEvent e){
System.out.println("Mouse was clicked");
timer.start();
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
});
ActionListener animation = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
repaint();
}
};
timer = new Timer(50, animation);
}
#Override
public void paintComponent(Graphics g) {
buffer = createImage(screenw, screenh);
bg = buffer.getGraphics();
int w = getWidth();
int h = getHeight();
double px = getWidth()/2;
double py = getHeight()/2;
bg.setColor(Color.BLACK);
bg.fillRect(0, 0, w, h); //black background
for (int j=0; j < 100; j++){ //make stars
starx[j] = gen.nextInt(w);
stary[j] = gen.nextInt(h);
starc[j] = new Color(gen.nextInt(100)+156, gen.nextInt(100)+156, gen.nextInt(100)+156);
bg.setColor(starc[j]);
bg.drawLine(starx[j], stary[j], starx[j]+2, stary[j]+2);
bg.drawLine(starx[j], stary[j]+2, starx[j]+2, stary[j]);
}
g.drawImage(buffer, 0, 0, null);
double xvel = -15;
double yvel = 10;
for (int j=0; j < 100; j++){ //store stars
starx[j] = gen.nextInt(w);
stary[j] = gen.nextInt(h);
starc[j] = new Color(gen.nextInt(100)+156, gen.nextInt(100)+156, gen.nextInt(100)+156);
}
Image test = createImage(200,200);
Graphics testg = test.getGraphics();
testg.drawLine(50,50,150,150);
g.drawImage(buffer, 0,0, null);
try {
Thread.sleep(33);
} catch (Exception e) {
e.printStackTrace();
}
bg.setColor(Color.BLACK);
bg.fillRect(0, 0, w, h); //black background
for (int j=0; j < 100; j++){ //draw stars
bg.setColor(starc[j]);
bg.drawLine(starx[j], stary[j], starx[j]+2, stary[j]+2);
bg.drawLine(starx[j], stary[j]+2, starx[j]+2, stary[j]);
}
bg.setColor(Color.BLUE);
if (i > 0){
for (int z=0; z < i-1; z++){
bg.drawLine(ptx.get(z), pty.get(z), ptx.get(z+1), pty.get(z+1));
}
}
bg.setColor(Color.CYAN);
bg.fillOval((int)px, (int)py, 25, 25); //planet
bg.setColor(Color.RED);
bg.fillRect((int)(x-5),(int)(y-5),10,10); //ship
double fg = (5*50000)/(Math.pow(dist(x,y,px,py),2));
double m = (y-py)/(x-px);
double ms = Math.sqrt(Math.abs(m));
if (m < 0) ms = -ms;
double xchg = fg;
double ychg = fg*ms;
if (x > px){
xchg = -xchg;
ychg = -ychg;
}
xvel += xchg;
yvel += ychg;
x += xvel;
y += yvel;
ptx.add((int)x);
pty.add((int)y);
i++;
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Gravity());
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
public static double dist(double x1, double y1, double x2, double y2){
double x = x2-x1;
double y = y2-y1;
return Math.sqrt((x*x)+(y*y));
}
}
Use a JComponent instead of a Canvas. You'll want to add the mouse listener to that object. You'll also need to set up the mouse listener in the constructor, not the paint() method.
Edit: You're doing to much in the paint() method as #AndrewThompson pointed out.
public Gravity() {
addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse was clicked");
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
});
}
#Override
public void paint(Graphics g) {
buffer = createImage(screenw, screenh);
bg = buffer.getGraphics();
...
bg.setColor(Color.BLACK);
bg.fillRect(0, 0, w, h); // black background
for (int j = 0; j < 100; j++) { // make stars
...
}
bg.drawImage(title, 100, 100, null);
g.drawImage(buffer, 0, 0, null);
double xvel = -15;
double yvel = 10;
for (int j = 0; j < 100; j++) { // store stars
...
}
Image test = createImage(200, 200);
Graphics testg = test.getGraphics();
testg.drawLine(50, 50, 150, 150);
g.drawImage(buffer, 0, 0, null);
bg.setColor(Color.BLACK);
bg.fillRect(0, 0, w, h); // black background
for (int j = 0; j < 100; j++) { // draw stars
...
}
bg.setColor(Color.BLUE);
if (i > 0) {
for (int z = 0; z < i - 1; z++) {
bg.drawLine(ptx.get(z), pty.get(z), ptx.get(z + 1), pty.get(z + 1));
}
}
bg.setColor(Color.CYAN);
bg.fillOval((int) px, (int) py, 25, 25); // planet
bg.setColor(Color.RED);
bg.fillRect((int) (x - 5), (int) (y - 5), 10, 10); // ship
....
ptx.add((int) x);
pty.add((int) y);
}
public static void main(String[] args) {
...
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
...
}
Notes about your code:
Avoid making fields public static. 99.9% of the time this is not necessary, and usually leads to trouble later.
The painting code seems to be unnecessarily using buffers--the test Image is not used at all currently!
I removed the while(true) loop, but noticed you're drawing an image, modifying the image, and then drawing the image again. You can probably do this in one go.
You should be able to avoid using an Image buffer altogether since you're creating a new one each time paint() is called, and clearing it at the beginning. Just draw your graphics directly to g.
Avoid doing I/O from within the paint() method. Load your images during construction or in a background thread.
Your paint() method is tying up the Thread that handles the mouse click event, due to the while (!started) loop that never exits. started is never true because the MouseListener's mouseClicked() is never called because the paint() method is waiting for started to be true! If you remove that loop, the while (true) loop will have a similar effect. Any mouse events that happen while paint() is running will be queued until paint() returns.

Custom ScrollPane using just a Panel or any other Container

I'm trying to mimic a ScrollPane by simply inheriting from a Panel which itself moves its child around.
Should be a simple task but the child doesn't get clipped properly, meaning if I scroll around using setScrollPosition(Point) the content is visible although its outside the parent Panel.
public class ScrollFrame
extends Container
{
public ScrollFrame() {
setLayout(null);
}
public void paint(Graphics g) {
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
super.paint(g);
}
public void setScrollPosition(Point p) {
setScrollPosition(p.x, p.y);
}
public void setScrollPosition(int x, int y) {
synchronized (getTreeLock()) {
Component component = getComponent(0);
int viewPortWidth = getWidth(),
viewPortHeight = getHeight(),
componentWidth = component.getWidth(),
componentHeight = component.getHeight(),
componentX = component.getX(),
componentY = component.getY();
if (x < 0) {
x = 0;
} else if (x > 0 && x + viewPortWidth > componentWidth) {
x = componentWidth - viewPortWidth;
if (x < 0)
x = 0;
}
if (y < 0) {
y = 0;
} else if (y > 0 && y + viewPortHeight > componentHeight) {
y = componentHeight - viewPortHeight;
if (y < 0)
y = 0;
}
component.setLocation(x * -1, y * -1);
validate();
}
}
public Point getScrollPosition() {
synchronized (getTreeLock()) {
Point p = getComponent(0).getLocation();
p.x *= -1;
p.y *= -1;
return p;
}
}
}
Problem: The child component added to the ScrollFrame is visible outside the boundaries of the ScrollFrame.
And finally a SSCCE for some C&P testing, just click into the red area and move the mouse up and down:
import java.awt.*;
import java.awt.event.*;
public class TestScrollPane extends Frame implements MouseListener,
MouseMotionListener
{
/* starting point */
public static void main(String[] args)
{
TestScrollPane window = new TestScrollPane();
window.setSize(800, 480);
window.setVisible(true);
}
/*
* a translucent element to be placed above all other components to receive
* the MouseEvents
*/
public class GlassPane extends Component
{
public void paint(Graphics g)
{
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
super.paint(g);
}
}
public class ScrollContainer extends Container
{
public ScrollContainer()
{
setLayout(null);
}
public void paint(Graphics g)
{
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
super.paint(g);
}
public void printComponents(Graphics g)
{
Component c = getComponent(0);
Point p = c.getLocation();
Graphics cg = g.create();
try {
cg.clipRect(0, 0, getWidth(), getHeight());
cg.translate(p.x * -1, p.y * -1);
c.paintAll(cg);
} finally {
cg.dispose();
}
}
public void setScrollPosition(Point p)
{
setScrollPosition(p.x, p.y);
}
public void setScrollPosition(int x, int y)
{
synchronized (getTreeLock()) {
Component component = getComponent(0);
int viewPortWidth = getWidth(), viewPortHeight = getHeight(), componentWidth = component
.getWidth(), componentHeight = component.getHeight(), componentX = component
.getX(), componentY = component.getY();
if (x < 0) {
x = 0;
} else if (x > 0 && x + viewPortWidth > componentWidth) {
x = componentWidth - viewPortWidth;
if (x < 0)
x = 0;
}
if (y < 0) {
y = 0;
} else if (y > 0 && y + viewPortHeight > componentHeight) {
y = componentHeight - viewPortHeight;
if (y < 0)
y = 0;
}
component.setLocation(x * -1, y * -1);
}
}
public Point getScrollPosition()
{
synchronized (getTreeLock()) {
Point p = getComponent(0).getLocation();
p.x *= -1;
p.y *= -1;
return p;
}
}
}
private ScrollContainer scrollPane;
private Panel scrollPaneContainer;
private GlassPane glassPane;
private boolean scrolling = false;
private Point scrollingStartMouse;
private Point scrollingStartPane;
public TestScrollPane()
{
/* simple test window */
super("TestScrollPane");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
setLayout(null);
/*
* the ScrollPane provides the ability to show only a limited of a much
* larger child element. Note that the ScrollPane is a container for
* only ONE element, but the child element may act as a container, e.g.
* a Panel
*/
scrollPane = new ScrollContainer();
scrollPane.addMouseListener(this);
scrollPane.setBounds(30, 50, 300, 300);
/*
* the element we place in the scrollpane, a panel with null layout to
* place the children
*/
scrollPaneContainer = new Panel();
scrollPaneContainer.setLayout(null);
/* add some random buttons for testing purposes */
for (int i = 0; i < 30; ++i) {
Button button = new Button("Click Me " + i);
button.addMouseListener(this);
button.setBounds(0, 40 * i, 100, 30);
scrollPaneContainer.add(button);
}
/*
* a translucent component on top of all elements placed inside the
* scrollPaneContainer to receive the MouseEvent's and properly scroll
* the ScrollPane or propagate the event
*/
glassPane = new GlassPane();
glassPane.setBounds(0, 0, 1, 1);
glassPane.addMouseListener(this);
glassPane.addMouseMotionListener(this);
/*
* we do need to add the GlassPane first to place it above all other
* elements
*/
// scrollPaneContainer.add(glassPane);
/*
* the GlassPane and the scrollPaneContainer need to have the same size.
* you have to set a size on the scrollPaneContainer else there won't be
* any scrolling ;)
*/
scrollPaneContainer.setSize(100, 1190);
scrollPaneContainer.setPreferredSize(new Dimension(100, 1190));
/* place the scrollPaneContainer (Panel) inside the ScrollPane */
scrollPane.add(scrollPaneContainer);
scrollPane.setBounds(30, 30, 150, 300);
glassPane.setBounds(30, 30, 30, 300);
Panel all = new Panel();
all.setLayout(null);
all.setBounds(30, 30, 400, 400);
all.add(glassPane);
all.add(scrollPane);
add(all);
}
/* MouseListener implementation */
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
if (e.getSource().equals(glassPane)) {
scrolling = false;
}
}
public void mousePressed(MouseEvent e)
{
if (e.getSource().equals(glassPane)) {
scrolling = true;
scrollingStartMouse = e.getPoint();
scrollingStartPane = scrollPane.getScrollPosition();
}
}
/* MouseMotionListener implementation */
public void mouseDragged(MouseEvent e)
{
if (scrolling) {
Point currentPos = e.getPoint();
int mouseDeltaX = currentPos.x - scrollingStartMouse.x;
int mouseDeltaY = currentPos.y - scrollingStartMouse.y;
scrollPane.setScrollPosition(scrollingStartPane.x - mouseDeltaX,
scrollingStartPane.y - mouseDeltaY);
}
}
public void mouseMoved(MouseEvent e)
{
}
void log(String message)
{
System.out.println(message);
}
void log(String message, MouseEvent e)
{
log(e.getComponent().getClass().getName() + ": " + message);
}
}

Drawing a line using a Mouse Motion Listener

I'm new at using actionListener and mouselistner. I want to track the Mouse movements and connect the dots as I go. So it will be one continuous line. I am using the MouseMotionListener every time I move the mouse across the screen and get a new set of points. I am not using mousePressed or mouseReleased.
Everytime I move the mouse, I can get every point of where my mouse's position is on my JPanel to show up on my results window, but in order to draw the line between two points, I'm not sure how to decipher between each different set of points so I can have a beginning and ending set of points to use for drawing a line? I checked through here and the API and I'm stuck.
I was asked to put more code and so I gave you my code.
I am basically creating a Jpane that tracks mouse movement when the Track Mouse button or Draw Track Radio button is pressed
These results will print out as (x,y) on the output screen
FYI: You can also draw circles once the Draw circles RadioButton is checked
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class MouseTest {
private JFrame frame;
private boolean tracking;
private boolean drawing;
private boolean connectdots;
private int xstart;
private int ystart;
private int xend;
private int y;
private int x;
private int yend;
private int borderWidth = 5;
String drawCircles = "Draw Circles";
String drawTrack = "Draw Track";
public static void main (String [] arg) {
MouseTest first = new MouseTest();
}//main
$
public MouseTest() {
tracking = false;
frame = new JFrame();
frame.setBounds(250,98,600,480);
frame.setTitle("Window number three");
Container cp = frame.getContentPane();
JButton track = new JButton("Track Mouse");
track.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
trackMouse();
}
});
JPanel top = new JPanel();
top.add(track);
cp.add(top,BorderLayout.NORTH);
MyPanel pane = new MyPanel();
cp.add(pane,BorderLayout.CENTER);
pane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
xstart = e.getX();
ystart = e.getY();
}
public void mouseReleased(MouseEvent e) {
xend = e.getX();
yend = e.getY();
if (xend < xstart) { int tmp = xstart; xstart = xend; xend = tmp; }
if (yend < ystart) { int tmp = ystart; ystart = yend; yend = tmp; }
frame.repaint();
}
});
pane.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
if (tracking) {
x = e.getX();
y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
});
JRadioButton circleButton = new JRadioButton(drawCircles);
circleButton.setMnemonic(KeyEvent.VK_B);
circleButton.setActionCommand(drawCircles);
circleButton.setSelected(false);
JRadioButton trackButton = new JRadioButton(drawTrack);
trackButton.setMnemonic(KeyEvent.VK_C);
ButtonGroup group = new ButtonGroup();
group.add(circleButton);
group.add(trackButton);
JPanel radioPanel = new JPanel(new GridLayout(2,0));
radioPanel.add(circleButton);
radioPanel.add(trackButton);
cp.add(radioPanel,BorderLayout.EAST);
drawing = false;
connectdots = false;
circleButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
public void actionPerformed(ActionEvent ae) {
tracking = !tracking;
drawCircles();
}
});
trackButton.addActionListener(new ActionListener() { //Set drawing to true when the button is clicked
public void actionPerformed(ActionEvent ae) {
drawing = false;
tracking = true;
connectDots();
}
});
frame.setVisible(true);
}//constructor
$
public void trackMouse() {
tracking = !tracking;
}//trackMouse
public void msg(String s) { //new method to simplify the system.out.print method
System.out.println(s);
}
public void drawCircles() {
drawing = true;
}//Allow Drawing of Circles
public void connectDots() {
connectdots = !connectdots;
}//Trying to use for connecting the mouse motion listener points when tracking
$
public class MyPanel extends JPanel {
ArrayList<Circle> circles = new ArrayList<Circle>();
public void paintComponent(Graphics g) {
int width = this.getWidth();
int height = this.getHeight();
msg("H = " + height + ", w = " + width);
g.setColor(Color.BLACK);
Circle c = new Circle(xstart, ystart);
circles.add(c);
if (drawing){
for(int k=0; k<circles.size(); k++){
circles.get(k).draw(g);
}
} // draw the circle
if (connectdots && tracking) { //trying to use for drawing the lines
g.drawLine(x,y,x,y);
}
for (int delta = 0; delta < borderWidth; delta++) {
g.drawRect(delta,delta,width-(2*delta),height-(2*delta));
}
if (xstart != xend || ystart != yend) {
int red = (int)(256*Math.random());
int green = (int)(256*Math.random());
int blue = (int)(256*Math.random());
g.setColor(new Color(red, green, blue));
msg("Colors are: " + red + " - " + green + " - " + blue );
msg("Drawing from: (" + xstart + ", " + ystart + ") to (" + xend + ", " + yend + ")");
msg("Width is " + (xend-xstart) + " - Height is " + (yend-ystart));
g.fillRect(xstart,ystart,xend-xstart,yend-ystart);
}
}
}
}
$
public class Circle {
// instance variables:
int radius; //random radius
int x, y; // coords of the center point
private Graphics g;
public Circle(int xIn, int yIn) {
radius = (int)(127*Math.random());
x = xIn;
y = yIn;
}
public void draw(Graphics g){
g.drawOval(x-radius, y-radius, radius, radius);
g.fillOval(x-radius, y-radius, radius, radius);
int red = (int)(256*Math.random());
int green = (int)(256*Math.random());
int blue = (int)(256*Math.random());
g.setColor(new Color(red, green, blue));
}
public int getX(int xstart) {
// TODO Auto-generated method stub
return x;
}
public int getY(int ystart) {
// TODO Auto-generated method stub
return y;
}
}
You just have to save x and y in some attribute for your class (like lastX and lastY.) When you get the event the second time, your first point coordinates are saved in your attributes and you can then draw your line. This new point has to be saved too to serve as your new lastX and lastY.
Even better: since you'll probably need to redraw your lines each frame (if you want a set of lines and not just a single line to be drawn each frame), use Point to save your coordinates and some kind of list like ArrayList. Save the full set of tracked points in an ArrayList<Point> and then draw each frame iterating over this list.
An example of an sscce:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class Foo3 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private boolean tracking = false;
private int x, y;
public Foo3() {
add(new JToggleButton(new AbstractAction("TrackMouse") {
public void actionPerformed(ActionEvent ae) {
trackMouse(ae);
}
}));
MyMouseAdapter myMA = new MyMouseAdapter();
addMouseMotionListener(myMA);
}
private void trackMouse(ActionEvent ae) {
JToggleButton toggleBtn = (JToggleButton) ae.getSource();
tracking = toggleBtn.isSelected();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void msg(String message) {
System.out.println(message);
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
if (tracking) {
x = e.getX();
y = e.getY();
msg("(" + x + ", " + y + ")");
}
}
}
private static void createAndShowGui() {
Foo3 mainPanel = new Foo3();
JFrame frame = new JFrame("MouseMotion Eg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Edit: Example 2
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class MouseTestHovercraft extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private static final int MAX_CLR = 5;
private static final Color CURRENT_LIST_COLOR = new Color(190, 190, 255);
private List<Color> colors = new ArrayList<Color>();
private boolean tracking = false;
private List<Point> currentList = null;
private BufferedImage bufferedImage = new BufferedImage(PREF_W, PREF_H,
BufferedImage.TYPE_INT_ARGB);
private Random random = new Random();
public MouseTestHovercraft() {
for (int redIndex = 0; redIndex < MAX_CLR; redIndex++) {
int r = (redIndex * 256) / (MAX_CLR - 1);
r = (r == 256) ? 255 : r;
for (int greenIndex = 0; greenIndex < MAX_CLR; greenIndex++) {
int g = (greenIndex * 256) / (MAX_CLR - 1);
g = (g == 256) ? 255 : g;
for (int blueIndex = 0; blueIndex < MAX_CLR; blueIndex++) {
int b = (blueIndex * 256) / (MAX_CLR - 1);
b = (b == 256) ? 255 : b;
Color c = new Color(r, g, b);
colors.add(c);
}
}
}
add(new JToggleButton(new AbstractAction("TrackMouse") {
public void actionPerformed(ActionEvent ae) {
trackMouse(ae);
}
}));
add(new JButton(new AbstractAction("Clear Image") {
public void actionPerformed(ActionEvent e) {
bufferedImage = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_ARGB);
repaint();
}
}));
MyMouseAdapter myMA = new MyMouseAdapter();
addMouseListener(myMA);
addMouseMotionListener(myMA);
}
private void trackMouse(ActionEvent ae) {
JToggleButton toggleBtn = (JToggleButton) ae.getSource();
tracking = toggleBtn.isSelected();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public void msg(String message) {
System.out.println(message);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bufferedImage, 0, 0, null);
if (currentList != null) {
drawList(g, currentList, CURRENT_LIST_COLOR, 1f);
}
}
private void drawList(Graphics g, List<Point> ptList, Color color,
float strokeWidth) {
if (ptList.size() > 1) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
g2.setStroke(new BasicStroke(strokeWidth));
for (int j = 0; j < ptList.size() - 1; j++) {
int x1 = ptList.get(j).x;
int y1 = ptList.get(j).y;
int x2 = ptList.get(j + 1).x;
int y2 = ptList.get(j + 1).y;
g2.drawLine(x1, y1, x2, y2);
}
g2.dispose();
}
}
private class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
if (tracking && e.getButton() == MouseEvent.BUTTON1) {
currentList = new ArrayList<Point>();
currentList.add(e.getPoint());
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (tracking && e.getButton() == MouseEvent.BUTTON1) {
currentList.add(e.getPoint());
Graphics2D g2 = bufferedImage.createGraphics();
Color color = colors.get(random.nextInt(colors.size()));
drawList(g2, currentList, color, 3f);
currentList = null;
repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (tracking && currentList != null) {
currentList.add(e.getPoint());
repaint();
}
}
}
private static void createAndShowGui() {
MouseTestHovercraft mainPanel = new MouseTestHovercraft();
JFrame frame = new JFrame("MouseMotion Eg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setResizable(false);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Problem with JScrollBar Display

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.

Categories