diff options
Diffstat (limited to 'src/jrummikub/view/impl')
-rw-r--r-- | src/jrummikub/view/impl/Board.java | 47 | ||||
-rw-r--r-- | src/jrummikub/view/impl/CustomBorder.java | 42 | ||||
-rw-r--r-- | src/jrummikub/view/impl/PlayerPanel.java | 185 | ||||
-rw-r--r-- | src/jrummikub/view/impl/StonePainter.java | 94 | ||||
-rw-r--r-- | src/jrummikub/view/impl/Table.java | 69 | ||||
-rw-r--r-- | src/jrummikub/view/impl/View.java | 87 |
6 files changed, 524 insertions, 0 deletions
diff --git a/src/jrummikub/view/impl/Board.java b/src/jrummikub/view/impl/Board.java new file mode 100644 index 0000000..1d7cc1a --- /dev/null +++ b/src/jrummikub/view/impl/Board.java @@ -0,0 +1,47 @@ +package jrummikub.view.impl; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Insets; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +import jrummikub.model.Stone; +import jrummikub.model.StoneColor; +import jrummikub.view.IBoard; + +@SuppressWarnings("serial") +public class Board extends JPanel implements IBoard { + private final static ImageIcon background = new ImageIcon(Board.class.getResource("/jrummikub/resource/wood.png")); + + Board() { + super(true); + + setBorder(new CustomBorder(Color.DARK_GRAY, 0, 1, 0, 1)); + } + + @Override + protected void paintComponent(Graphics g) { + Insets insets = getInsets(); + int x = insets.left, y = insets.top, width = getWidth()-insets.left-insets.right, height = getHeight()-insets.top-insets.bottom; + g = g.create(x, y, width, height); + + for(int xpos = 0; xpos < width; xpos += background.getIconWidth()) { + background.paintIcon(this, g, xpos, 0); + } + for(int xpos = -32; xpos < width; xpos += background.getIconWidth()) { + background.paintIcon(this, g, xpos, 75); + } + + // TODO Rest of painting code + + // FIXME Test code + StonePainter.paintStone(g, new Stone(1, StoneColor.ORANGE, false), + 0, 0, StonePainter.BOARD_SCALE); + StonePainter.paintStone(g, new Stone(10, StoneColor.BLUE, false), + 1, 0, StonePainter.BOARD_SCALE); + StonePainter.paintStone(g, new Stone(5, StoneColor.RED, false), + 0.5f, 1, StonePainter.BOARD_SCALE); + } +} diff --git a/src/jrummikub/view/impl/CustomBorder.java b/src/jrummikub/view/impl/CustomBorder.java new file mode 100644 index 0000000..3e79ce7 --- /dev/null +++ b/src/jrummikub/view/impl/CustomBorder.java @@ -0,0 +1,42 @@ +package jrummikub.view.impl; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Insets; + +import javax.swing.border.Border; + +class CustomBorder implements Border { + private Color color; + private int top, left, bottom, right; + + public CustomBorder(Color color, int top, int left, int bottom, int right) { + this.color = color; + this.top = top; + this.left = left; + this.bottom = bottom; + this.right = right; + } + + @Override + public Insets getBorderInsets(Component c) { + return new Insets(top, left, bottom, right); + } + + @Override + public boolean isBorderOpaque() { + return true; + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + g.setColor(color); + + g.fillRect(x, y, width, top); + g.fillRect(x, y+height-bottom, width, bottom); + g.fillRect(x, y, left, height); + g.fillRect(x+width-right, y, right, height); + } + +} diff --git a/src/jrummikub/view/impl/PlayerPanel.java b/src/jrummikub/view/impl/PlayerPanel.java new file mode 100644 index 0000000..5c29e7e --- /dev/null +++ b/src/jrummikub/view/impl/PlayerPanel.java @@ -0,0 +1,185 @@ +package jrummikub.view.impl; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.DecimalFormat; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JProgressBar; + +import jrummikub.util.Event; +import jrummikub.util.IEvent; +import jrummikub.view.IBoard; +import jrummikub.view.IPlayerPanel; + +@SuppressWarnings("serial") +public class PlayerPanel extends JPanel implements IPlayerPanel { + private final static DecimalFormat secondFormat = new DecimalFormat("00"); + + private Board board; + + private JLabel currentPlayerNameLabel; + private JButton sortByNumberButton; + private JButton sortByColorButton; + private JProgressBar timeBar; + private JButton endTurnButton; + + private Event sortByNumberEvent = new Event(); + private Event sortByColorEvent = new Event(); + private Event endTurnEvent = new Event(); + + + @Override + public IBoard getBoard() { + return board; + } + + @Override + public void setCurrentPlayerName(String playerName) { + currentPlayerNameLabel.setText(playerName); + } + + @Override + public + void setTimeLeft(int time) { + timeBar.setValue(time); + timeBar.setString(Integer.toString(time/60) + ":" + secondFormat.format(time%60)); + } + + @Override + public IEvent getSortByNumberEvent() { + return sortByNumberEvent; + } + + @Override + public IEvent getSortByColorEvent() { + return sortByColorEvent; + } + + @Override + public IEvent getEndTurnEvent() { + return endTurnEvent; + } + + + JPanel createLeftPanel() { + JPanel panel = new JPanel(); + panel.setPreferredSize(new Dimension(0, 0)); + GridBagLayout layout = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + panel.setLayout(layout); + panel.setOpaque(false); + + + currentPlayerNameLabel = new JLabel(); + currentPlayerNameLabel.setHorizontalAlignment(JLabel.CENTER); + currentPlayerNameLabel.setHorizontalTextPosition(JLabel.CENTER); + currentPlayerNameLabel.setVerticalAlignment(JLabel.CENTER); + currentPlayerNameLabel.setVerticalTextPosition(JLabel.CENTER); + currentPlayerNameLabel.setPreferredSize(new Dimension(180, 30)); + c.weightx = 0; + c.weighty = 1; + c.gridwidth = GridBagConstraints.REMAINDER; + c.insets = new Insets(25, 0, 0, 0); + layout.setConstraints(currentPlayerNameLabel, c); + panel.add(currentPlayerNameLabel); + + sortByNumberButton = new JButton("<html><center>Sort by<br>number"); + sortByNumberButton.setPreferredSize(new Dimension(85, 50)); + sortByNumberButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + sortByNumberEvent.fire(); + }}); + + c.gridwidth = GridBagConstraints.RELATIVE; + c.gridheight = GridBagConstraints.REMAINDER; + c.insets = new Insets(15, 0, 20, 5); + layout.setConstraints(sortByNumberButton, c); + panel.add(sortByNumberButton); + + sortByColorButton = new JButton("<html><center>Sort by<br>color"); + sortByColorButton.setPreferredSize(new Dimension(85, 50)); + sortByColorButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + sortByColorEvent.fire(); + }}); + + c.gridwidth = GridBagConstraints.REMAINDER; + c.insets = new Insets(15, 5, 20, 0); + layout.setConstraints(sortByColorButton, c); + panel.add(sortByColorButton); + + return panel; + } + + JPanel createRightPanel() { + JPanel panel = new JPanel(); + panel.setPreferredSize(new Dimension(0, 0)); + GridBagLayout layout = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + panel.setLayout(layout); + panel.setOpaque(false); + + timeBar = new JProgressBar(0, 60); + timeBar.setStringPainted(true); + timeBar.setPreferredSize(new Dimension(180, 30)); + c.weightx = 0; + c.weighty = 1; + c.gridwidth = GridBagConstraints.REMAINDER; + c.insets = new Insets(25, 0, 0, 0); + layout.setConstraints(timeBar, c); + panel.add(timeBar); + + endTurnButton = new JButton("End turn"); + endTurnButton.setPreferredSize(new Dimension(180, 50)); + endTurnButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + endTurnEvent.fire(); + }}); + + c.gridheight = GridBagConstraints.REMAINDER; + c.insets = new Insets(15, 0, 20, 0); + layout.setConstraints(endTurnButton, c); + panel.add(endTurnButton); + + return panel; + } + + + PlayerPanel() { + GridBagLayout layout = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + setLayout(layout); + + setBackground(Color.LIGHT_GRAY); + + JPanel leftPanel = createLeftPanel(); + c.fill = GridBagConstraints.BOTH; + c.weightx = 1; + c.weighty = 1; + c.gridheight = GridBagConstraints.REMAINDER; + layout.setConstraints(leftPanel, c); + add(leftPanel); + + board = new Board(); + c.weightx = 3; + layout.setConstraints(board, c); + add(board); + + JPanel rightPanel = createRightPanel(); + c.weightx = 1; + c.gridwidth = GridBagConstraints.REMAINDER; + layout.setConstraints(rightPanel, c); + add(rightPanel); + } +} diff --git a/src/jrummikub/view/impl/StonePainter.java b/src/jrummikub/view/impl/StonePainter.java new file mode 100644 index 0000000..db3a477 --- /dev/null +++ b/src/jrummikub/view/impl/StonePainter.java @@ -0,0 +1,94 @@ +package jrummikub.view.impl; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.Rectangle2D; + +import jrummikub.model.Stone; +import jrummikub.model.StoneColor; + +class StonePainter { + private static final float ASPECT_RATIO = 0.75f; + private static final float DEFAULT_WIDTH = 40; + private static final float CIRCLE_WIDTH = 0.5f; + + private static final Color BACKGROUND_COLOR = new Color(0.9f, 0.9f, 0.6f); + + public static final float BOARD_SCALE = 75.0f*ASPECT_RATIO/DEFAULT_WIDTH; + + + private static Color getColor(StoneColor color) { + switch(color) { + case BLACK: + return Color.BLACK; + case BLUE: + return Color.BLUE; + case ORANGE: + return new Color(1.0f, 0.6f, 0); + case RED: + return Color.RED; + } + + return null; + } + + public static void paintStone(Graphics g, Stone stone, float x, float y, float scale) { + if (g instanceof Graphics2D) { + ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } + + int width = (int)(DEFAULT_WIDTH*scale); + int height = (int)(DEFAULT_WIDTH*scale/ASPECT_RATIO); + + int xpos = (int)(x*width); + int ypos = (int)(y*height); + + // Paint background + g.setColor(BACKGROUND_COLOR); + g.fillRect(xpos, ypos, width, height); + + // Paint bevel border + g.setColor(BACKGROUND_COLOR.brighter().brighter()); + g.fillRect(xpos, ypos, 1, height); + g.setColor(BACKGROUND_COLOR.brighter()); + g.fillRect(xpos+1, ypos+1, 1, height-2); + + g.setColor(BACKGROUND_COLOR.brighter().brighter()); + g.fillRect(xpos, ypos, width, 1); + g.setColor(BACKGROUND_COLOR.brighter()); + g.fillRect(xpos+1, ypos+1, width-2, 1); + + g.setColor(BACKGROUND_COLOR.darker().darker()); + g.fillRect(xpos+width-1, ypos, 1, height); + g.setColor(BACKGROUND_COLOR.darker()); + g.fillRect(xpos+width-2, ypos+1, 1, height-2); + + g.setColor(BACKGROUND_COLOR.darker().darker()); + g.fillRect(xpos, ypos+height-1, width, 1); + g.setColor(BACKGROUND_COLOR.darker()); + g.fillRect(xpos+1, ypos+height-2, width-2, 1); + + // Paint number + g.setFont(new Font("SansSerif", Font.BOLD, height/4)); + FontMetrics fm = g.getFontMetrics(); + String value = Integer.toString(stone.getValue()); + Rectangle2D stringRect = fm.getStringBounds(value, g); + + g.setColor(getColor(stone.getColor()).darker()); + g.drawString(value, (int)(xpos+width/2-stringRect.getWidth()/2)+1, ypos+height/4+(fm.getAscent()-fm.getDescent())/2+1); + g.setColor(getColor(stone.getColor())); + g.drawString(value, (int)(xpos+width/2-stringRect.getWidth()/2), ypos+height/4+(fm.getAscent()-fm.getDescent())/2); + + // Paint circle + g.setColor(BACKGROUND_COLOR.darker()); + g.drawArc((int)(xpos+width/2-width*CIRCLE_WIDTH/2), (int)(ypos+height*0.65f-width*CIRCLE_WIDTH/2), (int)(width*CIRCLE_WIDTH), (int)(width*CIRCLE_WIDTH), 50, 170); + + g.setColor(BACKGROUND_COLOR.brighter()); + g.drawArc((int)(xpos+width/2-width*CIRCLE_WIDTH/2), (int)(ypos+height*0.65f-width*CIRCLE_WIDTH/2), (int)(width*CIRCLE_WIDTH), (int)(width*CIRCLE_WIDTH), -130, 170); + } +} diff --git a/src/jrummikub/view/impl/Table.java b/src/jrummikub/view/impl/Table.java new file mode 100644 index 0000000..c3c6a71 --- /dev/null +++ b/src/jrummikub/view/impl/Table.java @@ -0,0 +1,69 @@ +package jrummikub.view.impl; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import jrummikub.view.ITable; + +@SuppressWarnings("serial") +public class Table extends JPanel implements ITable { + private final static ImageIcon background = new ImageIcon(Board.class.getResource("/jrummikub/resource/felt.png")); + + private JLabel leftPlayerLabel, topPlayerLabel, rightPlayerLabel; + private JPanel innerPanel; + + + @Override + public void setLeftPlayerName(String playerName) { + leftPlayerLabel.setText(playerName); + } + + @Override + public void setTopPlayerName(String playerName) { + topPlayerLabel.setText(playerName); + } + + @Override + public void setRightPlayerName(String playerName) { + rightPlayerLabel.setText(playerName); + } + + Table() { + super(true); // set double buffered + setLayout(new BorderLayout()); + + leftPlayerLabel = new JLabel(); + leftPlayerLabel.setForeground(Color.WHITE); + add(leftPlayerLabel, BorderLayout.WEST); + + topPlayerLabel = new JLabel(); + topPlayerLabel.setHorizontalAlignment(JLabel.CENTER); + topPlayerLabel.setHorizontalTextPosition(JLabel.CENTER); + topPlayerLabel.setForeground(Color.WHITE); + add(topPlayerLabel, BorderLayout.NORTH); + + rightPlayerLabel = new JLabel(); + rightPlayerLabel.setForeground(Color.WHITE); + add(rightPlayerLabel, BorderLayout.EAST); + + innerPanel = new JPanel(); + innerPanel.setOpaque(false); + add(innerPanel, BorderLayout.CENTER); + } + + @Override + protected void paintComponent(Graphics g) { + for(int x = 0; x < getWidth(); x += background.getIconWidth()) { + for(int y = 0; y < getHeight(); y += background.getIconHeight()) { + background.paintIcon(this, g, x, y); + } + } + + // TODO Rest of painting code + } +} diff --git a/src/jrummikub/view/impl/View.java b/src/jrummikub/view/impl/View.java new file mode 100644 index 0000000..5b0295c --- /dev/null +++ b/src/jrummikub/view/impl/View.java @@ -0,0 +1,87 @@ +package jrummikub.view.impl; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +import javax.swing.JFrame; +import javax.swing.UIManager; + +import jrummikub.util.IListener; +import jrummikub.view.IPlayerPanel; +import jrummikub.view.ITable; +import jrummikub.view.IView; + +@SuppressWarnings("serial") +public class View extends JFrame implements IView { + private Table table; + private PlayerPanel playerPanel; + + private final static int PLAYER_PANEL_HEIGHT = 150; + + + public ITable getTable() { + return table; + } + + public IPlayerPanel getPlayerPanel() { + return playerPanel; + } + + + public View() { + super("JRummikub"); + + setSize(1000, 700); + setDefaultCloseOperation(EXIT_ON_CLOSE); + + setLayout(new BorderLayout()); + + table = new Table(); + add(table, BorderLayout.CENTER); + + playerPanel = new PlayerPanel(); + playerPanel.setBorder(new CustomBorder(Color.BLACK, 1, 0, 0, 0)); + playerPanel.setPreferredSize(new Dimension(0, PLAYER_PANEL_HEIGHT+1)); + add(playerPanel, BorderLayout.SOUTH); + } + + /** + * @param args + */ + public static void main(String[] args) { + // FIXME Only test main for GUI preview + String nativeLF = UIManager.getSystemLookAndFeelClassName(); + + try { + UIManager.setLookAndFeel(nativeLF); + } catch (Exception e) { + } + + View view = new View(); + + view.getPlayerPanel().setCurrentPlayerName("Player 1"); + view.getPlayerPanel().setTimeLeft(42); + view.getTable().setLeftPlayerName("Player 2"); + view.getTable().setTopPlayerName("Player 3"); + view.getTable().setRightPlayerName("Player 4"); + + view.getPlayerPanel().getSortByNumberEvent().add(new IListener() { + @Override + public void fire() { + System.out.println("'Sort by number' fired"); + }}); + view.getPlayerPanel().getSortByColorEvent().add(new IListener() { + @Override + public void fire() { + System.out.println("'Sort by color' fired"); + }}); + view.getPlayerPanel().getEndTurnEvent().add(new IListener() { + @Override + public void fire() { + System.out.println("'End turn' fired"); + }}); + + view.setVisible(true); + } +} |