# QBASIC to JAVA



## Geek4Life (Jan 30, 2008)

In order to increase my Understanding of JAVA, since at the moment I can do less with JAVA then i can in QB, I'm trying to convert/revamp a Yahtzee program i wrote in QB intro JAvA. Since JAVA is Ovject-Oriented, naturally a slightly different approach is neccessary. In order to do this I have a few problems i need to work out. For example:

How am I going to turn this (In QB):

```
INPUT "How many players will be playing"; P
DIM Player$(P)
DIM USCORE(P, 6)
DIM LSCORE(P, 7)
DIM BONUS(P)
DIM SCORE(P)
```
into JAVA (Summary: Define Array size of a Array (visible in all methods) based off info gathered in one method). I was thinking of making an Object Player to hold all this Data, but since the values of these variables are going to be determined by the main class i dont kow whether or not this would be the correct approach. Can someone please help straighten me out. I've gotten thus far in Java (Dealing with the n players factor provides a major roadblock in progress):


```
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JOptionPane;
import java.awt.Color;
import java.awt.Graphics;
/*import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;*/
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
/*import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;*/

public class Yahtzee extends JFrame{
    private JFrame error = new JFrame();
    private Random r = new Random();
    boolean hold[] = new boolean[5];
    die Die[] = new die[5];
    int sortDie[] = new int[5];
    int players;
    private JTextField playerintput;
    private final int MIN_PLAYERS = 2;
//    ScoreCard Scorecard[] = new ScoreCard[player]; 
    public Yahtzee() {
       for (int x = 0; x < 5; x++) {
           Die[x] = new die();
           addMouseListener(new Listen());
       }
    }
   
    public void paint (Graphics g) {
        
    }
    
    public void roll () {
        for (int x = 0; x < 5; x++) {
            if (!hold[x]) {
                Die[x].roll();
            }
        }
    }
    
    private class Listen implements MouseListener {      
        public void mouseClicked(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
    }
}
```
As you can see, I havent done much of anything except attempt to initialize some variables. Long explanation for what is probably a simple problem.

P.S. Attached for anyone curious is the full source of my QB Yahtzee in its final state (which is a bit excessive in approach and featured, but what can I say, I had fun writing it and didn't want to call it a wrap).


----------



## Nok1 (Feb 16, 2004)

If i'm understanding you correctly, I would go ahead and write a player class. Then inside your main somewhere, you'd initialize a new player class and initialize everything within that class. Then you'd refer to that instance of the player class whenever you needed to modify anything inside of it. 

By defining (or passing in) N players, you should should then create N player classes, and keep them in a set/list/array of some sort.


----------



## Geek4Life (Jan 30, 2008)

But if there just values, with no logic and no retun values, how's that going to work?


----------



## Chicon (Jul 29, 2004)

Hi Geek4Life,

Nok1 is right about writing a _Player_ class.
Also, you shouldn't focus about how to translate QBasic codings in Java.
Just think about the rules of the game and about the way you'll encapsulate them in the business logic part of your program.
Below, there's a classic design that shows how a desktop application is build.


```
[SIZE=2]
 _______________                ______________                ___________
|   GUI         | (4) refresh  |  Events      |              |  Business |
|               |<-------------|  Handler     | (3) response |    Logic  |
|  __ ___ _____ |              |              |<-------------|           |
| |    Active  ||  (1) event   |              |              |           |
| | Components |-------------->|              | (2) request  |           |
| |____________||              |              |------------->|           |
|_______________|              |______________|              |___________|

[U]GUI[/U] (Graphic User Interface)
- a collection of graphic components
- translates actor's actions into events;
  the actor is either the user or the system itself (e.g. a timer)

[U]Events Handler[/U]
- implements different event listeners
- translates events into requests
- may 'refresh' graphic components according to the received responses
- the central place where synchronization between tasks is operated

[U]Business Logic[/U]
- the black box that encapsulates rules, logics, light tasks like small computations,
  heavy tasks like ftp processes or media streamings
- context independent and therefore reusable in a different context (e.g. in a web application)
- objects provider (responses)  
[/SIZE]
```


----------



## Nok1 (Feb 16, 2004)

Geek4Life said:


> But if there just values, with no logic and no retun values, how's that going to work?


rough pseudocode:

```
class Player {
   string name;
   int fieldinfo0;
   double fieldinfo1;
   bool fieldinfo2;
   constructor for Player 
}

class MainProgramClass {
 
  int numPlayers
   Player[] players;

   public static void main(bla){
   numPlayers = x;
   players = new Players[numPlayers];
   Players[index i where i < x].name = "my Name!";
   Players[index i where i < x].fieldinfo0 = 5;
   Players[index i where i < x].fieldinfo1 = 5.0;
   Players[index i where i < x].fieldinfo2 = false;
   }
}
```
or you could make it a bit more complicated, and instead of using an array you could use a hashset, and that way if there's a "new player" you'd add the player to the set. If you do end up doing that, make sure to rewrite the hashCode() method of the player class in order for it to return at least pseudounique hashes.


----------



## Geek4Life (Jan 30, 2008)

Thanks Chicon, Your right, I was looking at this the wrong way, I shouldn't be trying to rebuild the old code, but rather create a new program that functions the same way, but is more appropriate to the language being written in. Thanks for straightening me out on that one.

Nok1: nice thought with the Hash, but my skill level isnt ready for that yet, perhaps ill revise this code and add that when I feel more comfortable about what I'm doing. I dont even know how Hash works yet.


----------



## Nok1 (Feb 16, 2004)

no prob man.

Feel free to come back for more help.


----------



## Geek4Life (Jan 30, 2008)

Quick question, should be a fairly easy one to answer: if I write a class that extends an Applet, I don't need a *main* method; however, if I extend a JFrame, it would appear that a *main* method is needed. So my questions are this:

1) Why is this?

2) Is there a way to extend a JFrame and not have a *main* method (or rather without a static method/block - as I have seen on several sites)?

3) When should one use a JFrame instead of an Applet and vice versa?

4) What's the Difference? (I already partially know the answer to this but i dont feel i know the complete answer).


----------



## Chicon (Jul 29, 2004)

Hi Geek4Life,

1) An applet is a program executed from a web browser. When a HTML page refers to an applet, the web browser launches a JVM in order to load and execute the applet.
When an applet is loading, it executes successively the coding in its methods *init* and *start*. 
Also, applets may be executed by *appletviewer* which is part of the Java Development Kit, *appletviewer* is more a tool for programmers.

2) Yes, it is possible to extend the *JFrame* class without *main* method. In a multi-framed desktop program, you may encounter a lot of different *JFrame* extensions without *main*.
The *main* method is still needed in the starter class; the latter may be without extension.
You may do this :

```
[SIZE=2]
public class MainFrame extends JFrame {
...
}[/SIZE]
```
The launcher class :

```
[SIZE=2]
public class Launcher() {
   public static void main(String[] args) {
      new MainFrame();
   }
}[/SIZE]
```
3) & 4)
- *JFrame* : only for desktop applications
- *Applet* or *JApplet*(the Swing applet) : only for web pages


----------



## Geek4Life (Jan 30, 2008)

Following your advise, I've got:


```
public class YahtGUI {
    public static void main (String[] Args) {
        new Yahtzee();
    }
}

import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.awt.Color;
import java.awt.Graphics;
/*import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;*/
import java.awt.event.MouseListener;
/*import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;*/

public class Yahtzee extends JFrame {
    JFrame error = new JFrame();
    Random r = new Random();
    boolean hold[] = new boolean[5];
    die Die[] = new die[5];
    int sortDie[] = new int[5];
    int players, rlcnt, round = 1, cc;
    String fieldname[] = {"Ones", "Twos", "Threes", "Fours", "Fives", "Sixes", "Bonus", "Upper Total", "3 of a Kind", "4 of a kind", "Full House", "Sml Straight", 
"Lrg Straight", "Yahtzee", "Chance", "Lower Total", "Grand Total"};
    private final int MIN_PLAYERS = 2;
    
    public Yahtzee() {
       addMouseListener(new Listen());
       players = Integer.parseInt(JOptionPane.showInputDialog("How Many Players will Be Playing"));
       if (players < MIN_PLAYERS) players = MIN_PLAYERS;
    }
    Player player[] = new Player[players];
    int p = 1;
    public void init() {
        for (int x = 0; x < 5; x++) { 
           Die[x] = new die();
        }
        for (int x = 0; x < players; x++) {
            player[x] = new Player();
            player[x].name = JOptionPane.showInputDialog("Player " + (x + 1) + " please enter your name");
        }
    }
   public void paint (Graphics g) {
       setSize(1000,1000);
//       setLocation(500,500);
       g.drawString(player[p].name, 510, 15);
       g.drawLine(500, 25, 500, 220);
       g.drawLine(650, 25, 650, 220);
       g.drawLine(585, 25, 585, 220);
       g.drawLine(500, 250, 500, 470);
       g.drawLine(650, 250, 650, 470);
       g.drawLine(500, 25, 650, 25);
       g.drawLine(500, 250, 650, 250);
       for (int c = 1; c <= 17; c++) {
         if (c <= 8) cc = c; else cc = c + 1;  
           g.drawLine(500, cc*25+20, 650, cc*25+20);
           g.drawString(fieldname[c - 1], 510, cc*25 + 15);
       }
   }
    
    public void roll () {
        for (int x = 0; x < 5; x++) {
            if (!hold[x]) {
                Die[x].roll();
            }
        }
    }
    
    private class Listen implements MouseListener {      
        public void mouseClicked(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
    }
}
```
when this runs, it runs the input for number of users but I see nothing beyond that, it says "Build Successful". and terminates. How do I get run the rest of the program?


----------



## Chicon (Jul 29, 2004)

At the end of the _Yahtzee_ constructor, just add the following lines :

```
[SIZE=2]
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when user clicks the top right corner X, the program will stop
setSize(1000,1000);
setVisible(true);
[/SIZE]
```
and remove the _setSize_ statement from the _paint_ method as it doesn't have any effect.


----------



## Geek4Life (Jan 30, 2008)

Okay, that explains that (I should have been able to figure out that i needed to make my Frame Visible, that makes since), now ive got tons an tons of errors, all of which have to do with an array index being out of bounds:


> Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1
> at Yahtzee.paint(Yahtzee.java:45)
> at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:734)
> at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:679)
> ...


I had a feeling some of this pertained to the player Object Array, so, in some simple toubleshooting, I commented that line out, which left me with just these errors:


> Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1
> at Yahtzee.paint(Yahtzee.java:45)
> at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:734)
> at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:679)
> ...


What do these errors mean (and, in for the short-term, how do I resolve them)?


----------



## Chicon (Jul 29, 2004)

> Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1
> at Yahtzee.paint(Yahtzee.java:45)


That means you have to check the line number 45 of your source exactly in the _paint_ method : the value of the index that produces the error is equal to 1.
Look at the _p_ index of the _player_ array.
It seems your _player_ array is not properly initialized.


----------



## Geek4Life (Jan 30, 2008)

That was my Initial thought too, which is why i tried commenting out the reference to the player array. But the same error messages come up: Line 45 is Simply:


```
g.drawLine(500, 25, 500, 220);
```
That's whats having me puzzled, i dont know whats wrong with that since it shouldn't be trying to do anything with the player array.


----------



## Geek4Life (Jan 30, 2008)

Here's the Current Code:


```
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseListener;

public class Yahtzee extends JFrame {
    JFrame error = new JFrame();
    Random r = new Random();
    boolean hold[] = new boolean[5];
    die Die[] = new die[5];
    int sortDie[] = new int[5];
    int players, rllcnt, round = 1, cc, p = 0;
    String fieldname[] = {"Ones", "Twos", "Threes", "Fours", "Fives", "Sixes", "Bonus", "Upper Total", "3 of a Kind", "4 of a kind", "Full House", "Sml Straight",
    "Lrg Straight", "Yahtzee", "Chance", "Lower Total", "Grand Total"};
    private final int MIN_PLAYERS = 2;
    
    public Yahtzee() {
       addMouseListener(new Listen());
       players = Integer.parseInt(JOptionPane.showInputDialog("How Many Players will Be Playing"));
       if (players < MIN_PLAYERS) players = MIN_PLAYERS;
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setSize(1000,1000);
//       setLocation(500,500);
       setVisible(true);
    }
    
    Player player[] = new Player[players];
    
    public void initnew () {
        for (int x = 0; x < 5; x++) { 
           Die[x] = new die();
        }
        
        for (int x = 0; x < players; x++) {
            player[x] = new Player();
            player[x].name = JOptionPane.showInputDialog("Player " + (x + 1) + " what is your name");
        }
        System.out.println(1);
    }
    
   public void paint (Graphics g) {
[COLOR="Blue"] //      g.drawString(player[0].name, 510, 15);
       g.drawLine(500, 25, 500, 220);  //Line 45  [/COLOR]
       g.drawLine(650, 25, 650, 220);
       g.drawLine(585, 25, 585, 220);
       g.drawLine(500, 250, 500, 470);
       g.drawLine(650, 250, 650, 470);
       g.drawLine(500, 25, 650, 25);
       g.drawLine(500, 250, 650, 250);   
       for (int c = 1; c <= 17; c++) {
         if (c <= 8) cc = c; else cc = c + 1;  
           g.drawLine(500, cc*25+20, 650, cc*25+20);
           g.drawString(fieldname[c - 1], 510, cc*25 + 15);
       }
   }
    
    private void roll () {
        for (int x = 0; x < 5; x++) {
            if (!hold[x]) Die[x].roll();
        }
        rllcnt++;
    }
    
    private void switchplayer() {
        p++;
        if (p > players) nextround();
        return;
    }
    
    private void nextround() {
        round++;
        p = 1;
    }
    
    private void sort () {
        for (int x = 0; x < 5; x++) {
            sortDie[x] = Die[x].getvalue();
        }
        for (int increment = sortDie.length / 2; increment > 0; increment = (increment == 2 ? 1 : (int) Math.round(increment / 2.2))) {
            for (int i = increment; i < sortDie.length; i++) {
                int temp = sortDie[i];
                for (int j = i; j >= increment && sortDie[j - increment] > temp; j -= increment){
                    sortDie[j] = sortDie[j - increment];
                    sortDie[j - increment] = temp;
                }
            }
        }
    }
    
    private class Listen implements MouseListener {      
        public void mouseClicked(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
    }
}
```
It would appear the Initnew() method is being ignored.


----------



## Chicon (Jul 29, 2004)

I didn't count the lines; did you check this line too ?
*g.drawString(fieldname[c - 1], 510, cc*25 + 15);*


----------



## Chicon (Jul 29, 2004)

Geek4Life said:


> It would appear the Initnew() method is being ignored.


I got it ! The _initnew_ method is not executed.
In the constructor, just before the _setDefaultCloseOperation_ statement, add the statement _initnew();_.
Forget my prior post, _fieldname_ is not the cause.


----------



## Geek4Life (Jan 30, 2008)

That doesn't solve the problem.

Same errors.

Though it should be notably mentioned that, if for the moment we pretended it was an Applet, while the initnew(); method is still ignored, as long as the reference to the player array is commented out, it will run smoothly. So why is it having problems as a JFrame?

Also, adding initnew(); at the end of the constructor, will cause for obvious errors, since:


```
Player player[] = new Player[players];
```
is going to be ignored. Which brings me back to the very thing i was having troubles with at the start of this, how to define an Array, usable in all methods of a class, based off a user-defined variable.


----------



## Chicon (Jul 29, 2004)

There's another mistake in the way you're initializing _player_ :
*Player[] player= new Player[players]*;

_players_ is equal to 1, therefore your array may only content 1 item. It's the reason why you've got an error while using index = 1.

Edit : I'm looking through the logic, I'm not sure about the value of _players_

Edit : Indeed, I was right ! The array is build with size 1. But the value of _players_ has changed.


----------



## Chicon (Jul 29, 2004)

Therefore, this should solve the error :

```
[SIZE=2]
    JFrame error = new JFrame();
    Random r = new Random();
    boolean hold[] = new boolean[5];
    die Die[] = new die[5];
    int sortDie[] = new int[5];
    int players, rllcnt, round = 1, cc, p = 0;
    String fieldname[] = {"Ones", "Twos", "Threes", "Fours", "Fives", "Sixes", "Bonus", "Upper Total", "3 of a Kind", "4 of a kind", "Full House", "Sml Straight",
    "Lrg Straight", "Yahtzee", "Chance", "Lower Total", "Grand Total"};
    private final int MIN_PLAYERS = 2;
    [COLOR=RED]Player[] player;[/COLOR]
    
    public Yahtzee() {
       addMouseListener(new Listen());
       players = Integer.parseInt(JOptionPane.showInputDialog("How Many Players will Be Playing"));
       if (players < MIN_PLAYERS) players = MIN_PLAYERS;
       [COLOR=RED]player = new Player[players];
       initnew();[/COLOR]
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setSize(1000,1000);
//       setLocation(500,500);
       setVisible(true);
    }
    
    [COLOR=RED]//Player player[] = new Player[players]; // to remove[/COLOR]
[/SIZE]
```


----------



## Geek4Life (Jan 30, 2008)

ah. That makes since and should solve it part of it.


----------



## Geek4Life (Jan 30, 2008)

Down to three Tiny errors:



> Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
> at Yahtzee.initnew(Yahtzee.java:40)
> at Yahtzee.<init>(Yahtzee.java:29)
> at YahtGUI.main(YahtGUI.java:3)
> Java Result: 1


What's wrong with the logic here? JAVA arrays begin at zero, and run to the number exclusive, so why is there an array index out of bounds problem?


----------



## Chicon (Jul 29, 2004)

Please post a new version of your _Yahtzee_ class.


----------



## Geek4Life (Jan 30, 2008)

Never mind, I got it actually. For now, at least.


----------



## Geek4Life (Jan 30, 2008)

When I execute it it appears to have a transparent Background. Not to mention the fact that it opens in Lower-right hand corner, with it hanging off the screen, and when I move it, the bottom text creates a black trail. This trail can be removed if I switch to another window then come back to it, though. How do I fix this? Hopefully this explanation makes sense, since i can't seem to upload an images of it.


----------



## Chicon (Jul 29, 2004)

Hi Geek4Life,

When using complex Java API's like some Swing components, it is always a good idea to have a read of their documentation or familiarly _Javadoc_ : http://java.sun.com/javase/6/docs/api/


> Not to mention the fact that it opens in Lower-right hand corner, with it hanging off the screen,


Use the _setLocation(int x, int y)_ method to place your frame at the right location :
- _x_ is the number of pixels from the left border of the screen
- _y_ is the number of pixels from the top border of the screen.


> When I execute it it appears to have a transparent Background.


It is not usual to directly draw in the container of a _JFrame_ as the frame is a kind of multi-layered panes. And one of these panes, the _GlassRootPane_ is transparent by default.
Personally, when I have to design an image, I use a class that implements the _Icon_ interface and then, when the design is done, I put the image inside a _JLabel_ which has a native _setIcon_ method and I add the _JLabel_ to the frame container.
It makes the image more consistent (it even works for animated image) because the visual synchronization is automatically granted while using containers properly.
If you're interested, I may post the code using an animated image.


----------



## Geek4Life (Jan 30, 2008)

All right, I'll read over that. But for the moment, are you telling me I need to create a new pannel, add that to the Frame, and draw to _that_? Also, is there a way to quickly set the window status to Maximized (so it will fill up the entire screen)?


----------



## Chicon (Jul 29, 2004)

Here's an example :

```
[SIZE=2]
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class FrameDemo extends JFrame {
    // [COLOR=Red]To get the screen size of the computer[/COLOR]
    final private int WIDTH = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    final private int HEIGHT = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    
    private MyIcon icon;
    private JLabel label;
    private Listener listener;
    
    
    public FrameDemo() {
        super("Frame Demo");
        initComponents();
    }

    private void initComponents() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocation(0,0);
        setSize(WIDTH, HEIGHT);
        icon = new MyIcon();
        label = new JLabel();
        label.setIcon(icon);
        label.setLocation(0,0); // location inside the frame pane
        listener = new Listener();
        label.addMouseListener(listener);
        getContentPane().add(label);
        setVisible(true);
    }
    
    private class MyIcon implements Icon {
        public void paintIcon(Component c, Graphics g, int x, int y) {
            // fill a light-gray background
            g.setColor(Color.LIGHT_GRAY);
            g.fillRect(0, 0, WIDTH, HEIGHT);
            // draw a blue string with 'Courier New' font
            g.setColor(Color.BLUE);
            g.setFont(new Font("Courier New", Font.BOLD, 32));
            g.drawString("Frame Demo", 200, 300);
        }

        public int getIconWidth() {
            return WIDTH; 
        }

        public int getIconHeight() {
            return HEIGHT; 
        }
    }
    
    private class Listener implements MouseListener {
        public void mouseClicked(MouseEvent e) {}

        public void mousePressed(MouseEvent e) {}

        public void mouseReleased(MouseEvent e) {}

        public void mouseEntered(MouseEvent e) {}
        
        public void mouseExited(MouseEvent e) {}
     }
}[/SIZE]
```


----------



## Geek4Life (Jan 30, 2008)

Wait - you said Icon's even work with animation - do you mean animation as in animated gif's or as in actually drawing animation?


----------



## Chicon (Jul 29, 2004)

Geek4Life said:


> Wait - you said Icon's even work with animation - do you mean animation as in animated gif's or as in actually drawing animation?


No, I didn't mean animated .GIF.
In fact, to produce animated effects in Swing, we have to use the _Timer_ class provided by the _javax.swing_ package. The _Timer_ generates an _ActionEvent_ at regular lapse of time defined by the user. Each event is handled by an _ActionListener_ which _actionPerformed_ method is merely used to refresh the image container.


----------



## Chicon (Jul 29, 2004)

I've build a small example using a timer : when the frame is loaded, the user has to click on the frame to start the timer. The pane will display random horizontal lines of different colours with a rate of 100 by second. When the user clicks again, the timer stops and the pane is reset to black.

```
[SIZE=2]
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;

public class MainFrame extends JFrame {
	private Listener listener = new Listener();
	private Timer timer = new Timer(10, listener);
	private MIcon icon = new MIcon();
	private JLabel label = new JLabel(icon);

	public MainFrame() {
		super("Demo");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocation(100, 100);
		label.addMouseListener(listener);
		this.getContentPane().add(label);
		this.pack();
		this.setVisible(true);
	}

	private class Listener implements ActionListener, MouseListener {
		@Override
		public void mouseClicked(MouseEvent e) {
			if (timer.isRunning()) {
				timer.stop();
				icon.reset();
				label.repaint();
			} else
				timer.start();
		}

		@Override
		public void mouseEntered(MouseEvent e) {
		}

		@Override
		public void mouseExited(MouseEvent e) {
		}

		@Override
		public void mousePressed(MouseEvent e) {
		}

		@Override
		public void mouseReleased(MouseEvent e) {
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			icon.randomHorizontal();
			label.repaint();
		}
	}

	private class MIcon implements Icon {
		final private int WIDTH = 240;
		final private int HEIGHT = 180;
		private BufferedImage image;
		private Random seed;

		private MIcon() {
			image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
			reset();
			seed = new Random();
		}

		@Override
		public int getIconHeight() {
			return HEIGHT;
		}

		@Override
		public int getIconWidth() {
			return WIDTH;
		}

		@Override
		public void paintIcon(Component c, Graphics g, int x, int y) {
			g.drawImage(image, 0, 0, null);
		}

		public void randomHorizontal() {
			int line = seed.nextInt(HEIGHT);
			int red = seed.nextInt(256);
			int green = seed.nextInt(256);
			int blue = seed.nextInt(256);
			Color color = new Color(red, green, blue);
			for (int i = 0; i < WIDTH; i++) {
				image.setRGB(i, line, color.getRGB());
			}
		}

		public void reset() {
			for (int i = 0; i < WIDTH; i++) {
				for (int j = 0; j < HEIGHT; j++) {
					image.setRGB(i, j, Color.BLACK.getRGB());
				}
			}
		}
	}
}
[/SIZE]
```
The launcher class :

```
[SIZE=2]
public class Demo {

	public static void main(String[] args) {
		new MainFrame();

	}
}[/SIZE]
```


----------



## Geek4Life (Jan 30, 2008)

Okay, I don't know if that's the appropriate approach for this particular situation....If everything is reletive, the Icon needs to change relative to the information given. From the looks of your example it appears tha all the change is taking place within the Icon. Correct me if I'm wrong, please. What are my other options besides using an Icon to draw to?


----------



## Chicon (Jul 29, 2004)

To go back to your problem, as you were drawing a grid with text in it, you may use a layout manager called GridLayout.
With that layout manager, you may define a grid with the number of rows and columns you want.
In each cell of the grid, you may add a label that contains the text you want and you may decorate each label with a border if you want to visualize the grid.
I must leave now. I'll post a small example as soon as I come back.


----------



## Chicon (Jul 29, 2004)

Here's an example :

```
[SIZE=2]
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;

public class GridDemo extends JFrame {
    final private String[] text = { "One", "Two", "Three", "Four", "Five", "Six" };
    final Border border = BorderFactory.createLineBorder(Color.BLACK);
    final LayoutManager grid = new GridLayout(2,3);
    private JLabel[] label;
        
    public GridDemo() {
        super("GridLayout Demo");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocation(100, 100);
        this.setResizable(false);
        this.getContentPane().setPreferredSize(new Dimension(300,60));
        this.getContentPane().setLayout(grid);
        grid.preferredLayoutSize(this.getContentPane());
        label = new JLabel[6];
        for (int i = 0; i < 6; i++) {
            label[i] = new JLabel();
            label[i].setBorder(border);
            label[i].setHorizontalAlignment(JLabel.CENTER);
            label[i].setText(text[i]);
            this.getContentPane().add(label[i]);
        }
        this.pack();
        this.setVisible(true);
    }
}[/SIZE]
```


----------



## Geek4Life (Jan 30, 2008)

I hate to sound fussy but my lack of comprehensive JAVA knowledge leaves me no choice. Again, though this seems to have the potential for possible use it also seems a little bit lacking. Perhaps if I give a description of its intended purpose you could help me find a suitable means of accomplishing it. 

For this part, I'm designing an Interactive ScoreCard, where the user will click in the area of the Catagory they want to score their dice to. Also, as long as a Catagory has not yet been scored this score card will display during every die roll what the user would get in every catagory if they scored their dice now.

The other key concept that seems lacking in both of your proposals is the ability to change the information stored within based of a user-initiated event.

Take a look at attached image for a rough protype of the kind of interface I'm trying to achieve.


----------



## Chicon (Jul 29, 2004)

As a beginner, you should start with something less heavy. Java Swing is a huge package with numerous components which functionality and configuration are not easy to explain.
Also, instead of building a grid for each player, you may build only one grid which number of columns depends on the number of players.
Example with 3 players :

```
[SIZE=2]
------------------------------------------------
|  Category  | Player 1 | Player 2 | Player 3  |
|------------|----------|----------|-----------|
|    Ones    |          |          |           |
|------------|----------|----------|-----------|
|    Twos    |          |          |           |
|------------|----------|----------|-----------|
.
.
|------------|----------|----------|-----------|
|  Total     |          |          |           |
------------------------------------------------[/SIZE]
```
- Each cell contains a label;
- a mouse listener is assigned to each label that contains _Ones_, _Twos_, ... and so on;
- the 'active' player's name is coloured in another colour than the others' name
- when a player clicks on a 'listened' label, his column is updated according to the value of his dices :
if he wins, then game over otherwise his name colour and the next player's one change.

Following the example of my prior posts, you should easily build this one.
Personally, when I write a Swing application, I start to build my GUI and focus to make it show what I want it to display. At that stage of development, the logic is not yet needed as it can be written later even in a separate package.


----------



## Geek4Life (Jan 30, 2008)

I understand this may be a dificult interface to create - and I'm willing to except those challanges - unfortunately I can't make the interface simpler sense in a sense all I'm doing is giving the program I wrote a year ago in QBASIC a much more user-friendly GUI, instead of a sheerly text based version I had before. The challanges may be many but the learning opportunities are endless...


----------



## Geek4Life (Jan 30, 2008)

BUMP!

Would this work, draw a blank version of the Grid (with labels) and then draw to the Glass pane the details. Would this work?


----------



## Chicon (Jul 29, 2004)

Geek4Life said:


> BUMP!
> 
> Would this work, draw a blank version of the Grid (with labels) and then draw to the Glass pane the details. Would this work?


Hi Geek4Life,

Yes, it is possible. You should have a read on the following page :
http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html
Also, there's an example of how to use the glass pane on this page.


----------

