I made the class Room:
public class Room {
private Seat[][] seats;
public Room() {
seats = new Seat[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
seats[i][j] = new Seat(i, j);
}
}
}
public Seat[][] getSeats() {
return seats;
}
public void book(int x, int y) {
if (seats[x][y].getStatus() == AVAILABLE) {
seats[x][y].book();
}
}
public void buy(int x, int y) {
if (seats[x][y].getStatus() == BOOKED) {
seats[x][y].buy();
}
}
}
Pretty simple i think. A room has seats (100), you can get the seats (needed for the GUI), you can book a seat at a certain position, and you can buy a seat.
The Seat class is also very simple:
public class Seat {
private Status status;
private int x, y;
public Seat(int x, int y) {
status = AVAILABLE;
this.x = x;
this.y = y;
}
public void book() {
if (status == AVAILABLE) {
status = BOOKED;
}
}
public void buy() {
if (status == BOOKED) {
status = SOLD;
}
}
public Status getStatus() {
return status;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
It has a position (x,y). And a status(available, booked, sold). You can buy a seat, and book a seat. Before buying i check if it's booked, before booking i chekc if it's available.
+ some getters. getX and getY actually isn't used...
The status class(enum)
public enum Status {
AVAILABLE,
BOOKED,
SOLD
}
..not much to say..
Thus far the model.
Gui:
GridButton:
public class GridButton extends JButton implements ActionListener {
private boolean selected;
public GridButton(String text) {
super(text);
setBackground(Color.GREEN);
selected = false;
setBorderPainted(false);
setFocusable(false);
addActionListener(this);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
if (selected) {
g2.setStroke(new BasicStroke(5));
}
g2.drawRect(0, 0, getWidth(), getHeight());
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public void actionPerformed(ActionEvent e) {
selected = !selected;
}
}
A very simple button-class, it has a boolean selected to know if the button is selected or not. The constructor takes a string that string is the text on the button.
In this case it's a number. I do setBorderPainted(false); AND setFocusable(false); So it looks less like a button.
It has methods to get and set the selected state (isSelected(), and setSelected() ) . Upon clicking it will change its selection state automatically (actionperformed method)
Then a small paintComponent method to draw a selection box around it if it's selected.
The main frame:
import gridHelp.model.Room;
import gridHelp.model.Seat;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class View extends JFrame {
private GridButton[][] buttons;
private Room room;
public View() {
>Constructor..see further<
}
public void book() {
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
if (buttons[i][j].isSelected()) {
room.book(i, j);
buttons[i][j].setSelected(false);
}
}
}
update(room.getSeats());
}
public void buy() {
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
if (buttons[i][j].isSelected()) {
room.buy(i, j);
buttons[i][j].setSelected(false);
}
}
}
update(room.getSeats());
}
public void update(Seat[][] seats) {
for (int i = 0; i < seats.length; i++) {
for (int j = 0; j < seats[i].length; j++) {
switch (seats[i][j].getStatus()) {
case AVAILABLE:
buttons[i][j].setBackground(Color.GREEN);
break;
case BOOKED:
buttons[i][j].setBackground(Color.YELLOW);
break;
case SOLD:
buttons[i][j].setBackground(Color.RED);
break;
}
}
}
repaint();
}
}
It has a book and buy method (when you click the book and buy button).
It will loop trough all the buttons, check if it's selected (isSelected() ) and then book or buy it.
Then deselect all buttons and call the update(..) method.
The update method will loop trough all the seats of the room, and dependant of the status, change the color of the button. Then repaint itself. Done.
I think that, even though it may be a lot of code. It's very simple code with easy methods.
.. And it all makes sence:
a room that has seats and the buy and book methods take an x and y parameter
a seat that has a status(available, booked, sold) also with a buy and book method.
a frame that has buttons, a book and buy method which will invoke book and buy on all the seats that correspond to each button that was selected.
buttons that can be selected, and upon selecting it has a black, broader border.
... and then there's the constructor of the frame... it's always ugly code :P
super();
room = new Room();
buttons = new GridButton[10][10];
JPanel centerPanel = new JPanel(new GridLayout(10, 0));
JPanel southPanel = new JPanel(new GridLayout(0, 3));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
GridButton gridbutton = new GridButton(""+ ((i * 10) + j + 1));
buttons[i][j] = gridbutton;
centerPanel.add(gridbutton);
}
}
JButton bookButton = new JButton("book");
bookButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
book();
}
});
JButton buyButton = new JButton("buy");
buyButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buy();
}
});
JButton quitButton = new JButton("quit");
quitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
System.exit(0);
}
});
southPanel.add(bookButton);
southPanel.add(buyButton);
southPanel.add(quitButton);
add(centerPanel, BorderLayout.CENTER);
add(southPanel, BorderLayout.SOUTH);
pack();