diff --git a/Mines/bin/mines/StartFrame$1.class b/Mines/bin/mines/StartFrame$1.class index ed09786..58b74f4 100644 Binary files a/Mines/bin/mines/StartFrame$1.class and b/Mines/bin/mines/StartFrame$1.class differ diff --git a/Mines/bin/mines/StartFrame$2.class b/Mines/bin/mines/StartFrame$2.class index e8c3734..a24ade9 100644 Binary files a/Mines/bin/mines/StartFrame$2.class and b/Mines/bin/mines/StartFrame$2.class differ diff --git a/Mines/bin/mines/StartFrame$3.class b/Mines/bin/mines/StartFrame$3.class index a724504..65dbd7a 100644 Binary files a/Mines/bin/mines/StartFrame$3.class and b/Mines/bin/mines/StartFrame$3.class differ diff --git a/Mines/bin/mines/StartFrame$4.class b/Mines/bin/mines/StartFrame$4.class new file mode 100644 index 0000000..3c9ddd0 Binary files /dev/null and b/Mines/bin/mines/StartFrame$4.class differ diff --git a/Mines/bin/mines/StartFrame$5.class b/Mines/bin/mines/StartFrame$5.class new file mode 100644 index 0000000..e61c86a Binary files /dev/null and b/Mines/bin/mines/StartFrame$5.class differ diff --git a/Mines/bin/mines/StartFrame.class b/Mines/bin/mines/StartFrame.class index 754e2bd..5cd7180 100644 Binary files a/Mines/bin/mines/StartFrame.class and b/Mines/bin/mines/StartFrame.class differ diff --git a/Mines/src/mines/StartFrame.java b/Mines/src/mines/StartFrame.java index 8fbedbe..6ac04b2 100644 --- a/Mines/src/mines/StartFrame.java +++ b/Mines/src/mines/StartFrame.java @@ -1,17 +1,27 @@ package mines; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Dimension; import java.awt.Font; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; +import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.geom.RoundRectangle2D; +import javax.swing.BorderFactory; import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.UIManager; +import javax.swing.plaf.FontUIResource; /** * Game start menu frame @@ -34,73 +44,260 @@ public class StartFrame extends JFrame { private static final int HARD_COLUMNS = 25; private static final int HARD_MINES = 100; + // Colors for modern look + private static final Color PRIMARY_COLOR = new Color(66, 133, 244); + private static final Color SECONDARY_COLOR = new Color(52, 168, 83); + private static final Color ACCENT_COLOR = new Color(251, 188, 5); + private static final Color DANGER_COLOR = new Color(234, 67, 53); + private static final Color BACKGROUND_COLOR = new Color(248, 250, 252); + private static final Color CARD_COLOR = new Color(255, 255, 255); + private static final Color TEXT_COLOR = new Color(30, 41, 59); + private static final Color TEXT_LIGHT_COLOR = new Color(100, 116, 139); + + // Difficulty levels + private static final String[] DIFFICULTIES = { + "Easy (16x16) - 30 mines", + "Medium (20x20) - 60 mines", + "Hard (25x25) - 100 mines" + }; + + private JComboBox difficultyComboBox; + /** * StartFrame constructor */ public StartFrame() { + // Set UI defaults for modern look + setUIFont(new FontUIResource("Segoe UI", Font.PLAIN, 14)); + UIManager.put("ComboBox.background", CARD_COLOR); + UIManager.put("ComboBox.foreground", TEXT_COLOR); + UIManager.put("ComboBox.selectionBackground", PRIMARY_COLOR); + UIManager.put("ComboBox.selectionForeground", Color.WHITE); + UIManager.put("Button.arc", 15); + UIManager.put("Panel.background", BACKGROUND_COLOR); + setTitle("Minesweeper"); - setSize(400, 350); + setSize(450, 400); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setResizable(false); + setBackground(BACKGROUND_COLOR); - JPanel mainPanel = new JPanel(new BorderLayout()); + // Main panel with gradient background + JPanel mainPanel = new JPanel(new BorderLayout()) { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Subtle gradient background + GradientPaint gp = new GradientPaint(0, 0, BACKGROUND_COLOR, 0, getHeight(), + new Color(226, 232, 240)); + g2d.setPaint(gp); + g2d.fillRect(0, 0, getWidth(), getHeight()); + } + }; + mainPanel.setOpaque(true); + + // Title section + JPanel titlePanel = new JPanel(new BorderLayout()); + titlePanel.setOpaque(false); + titlePanel.setBorder(BorderFactory.createEmptyBorder(40, 0, 30, 0)); - // Title label - JLabel titleLabel = new JLabel("Minesweeper", JLabel.CENTER); - titleLabel.setFont(new Font("Arial", Font.BOLD, 36)); - titleLabel.setBorder(new javax.swing.border.EmptyBorder(40, 0, 20, 0)); - mainPanel.add(titleLabel, BorderLayout.NORTH); + // Custom title label with shadow effect + JLabel titleLabel = new JLabel("Minesweeper", JLabel.CENTER) { + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Draw shadow + g2d.setColor(new Color(0, 0, 0, 20)); + g2d.setFont(getFont()); + g2d.drawString(getText(), 2, getHeight() - 10); + + // Draw text + super.paintComponent(g); + } + }; + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 42)); + titleLabel.setForeground(PRIMARY_COLOR); + titlePanel.add(titleLabel, BorderLayout.CENTER); + + // Subtitle + JLabel subtitleLabel = new JLabel("Classic Game with Modern Design", JLabel.CENTER); + subtitleLabel.setFont(new Font("Segoe UI", Font.ITALIC, 14)); + subtitleLabel.setForeground(TEXT_LIGHT_COLOR); + subtitleLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + titlePanel.add(subtitleLabel, BorderLayout.SOUTH); + + mainPanel.add(titlePanel, BorderLayout.NORTH); + + // Content card panel + JPanel cardPanel = new JPanel(new GridBagLayout()); + cardPanel.setOpaque(true); + cardPanel.setBackground(CARD_COLOR); + cardPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 40, 0, 40), + BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(226, 232, 240), 1, true), + BorderFactory.createEmptyBorder(30, 30, 30, 30) + ) + )); - // Difficulty buttons panel - JPanel buttonPanel = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; - gbc.insets = new Insets(10, 80, 10, 80); + gbc.insets = new Insets(10, 0, 10, 0); + + // Difficulty label + JLabel difficultyLabel = new JLabel("Select Difficulty:"); + difficultyLabel.setFont(new Font("Segoe UI", Font.BOLD, 16)); + difficultyLabel.setForeground(TEXT_COLOR); + gbc.insets = new Insets(0, 0, 15, 0); + cardPanel.add(difficultyLabel, gbc); - // Easy button - JButton btnEasy = new JButton("Easy (16x16)"); - btnEasy.setFont(new Font("Arial", Font.PLAIN, 16)); - btnEasy.setPreferredSize(new Dimension(200, 45)); - btnEasy.addActionListener(new ActionListener() { + // Difficulty ComboBox + difficultyComboBox = new JComboBox(DIFFICULTIES) { @Override - public void actionPerformed(ActionEvent e) { - startGame(EASY_ROWS, EASY_COLUMNS, EASY_MINES); + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Draw rounded background + g2d.setColor(getBackground()); + g2d.fill(new RoundRectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1, 15, 15)); + g2d.setColor(new Color(203, 213, 225)); + g2d.draw(new RoundRectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1, 15, 15)); + + // Draw selected item + if (getSelectedIndex() != -1) { + g2d.setColor(getForeground()); + g2d.setFont(getFont()); + g2d.drawString(getSelectedItem().toString(), 15, getHeight() / 2 + 5); + } + + // Draw arrow + int arrowX = getWidth() - 30; + int arrowY = getHeight() / 2; + g2d.setColor(TEXT_LIGHT_COLOR); + g2d.fillPolygon( + new int[]{arrowX, arrowX + 8, arrowX + 4}, + new int[]{arrowY - 3, arrowY - 3, arrowY + 3}, + 3 + ); } - }); - buttonPanel.add(btnEasy, gbc); + }; + difficultyComboBox.setPreferredSize(new Dimension(300, 45)); + difficultyComboBox.setFont(new Font("Segoe UI", Font.PLAIN, 15)); + difficultyComboBox.setBackground(CARD_COLOR); + difficultyComboBox.setForeground(TEXT_COLOR); + difficultyComboBox.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); + gbc.insets = new Insets(0, 0, 25, 0); + cardPanel.add(difficultyComboBox, gbc); - // Medium button - JButton btnMedium = new JButton("Medium (20x20)"); - btnMedium.setFont(new Font("Arial", Font.PLAIN, 16)); - btnMedium.setPreferredSize(new Dimension(200, 45)); - btnMedium.addActionListener(new ActionListener() { + // Start button with modern design + JButton startButton = new JButton("Start Game") { @Override - public void actionPerformed(ActionEvent e) { - startGame(MEDIUM_ROWS, MEDIUM_COLUMNS, MEDIUM_MINES); + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Draw gradient button + GradientPaint gp; + if (getModel().isArmed()) { + gp = new GradientPaint(0, 0, SECONDARY_COLOR.darker(), 0, getHeight(), + new Color(45, 150, 70)); + } else if (getModel().isRollover()) { + gp = new GradientPaint(0, 0, new Color(60, 180, 90), 0, getHeight(), + SECONDARY_COLOR.darker()); + } else { + gp = new GradientPaint(0, 0, SECONDARY_COLOR, 0, getHeight(), + new Color(45, 150, 70)); + } + g2d.setPaint(gp); + g2d.fill(new RoundRectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1, 20, 20)); + + // Draw text + g2d.setColor(Color.WHITE); + g2d.setFont(getFont()); + String text = getText(); + int textWidth = g2d.getFontMetrics().stringWidth(text); + int textHeight = g2d.getFontMetrics().getHeight(); + g2d.drawString(text, (getWidth() - textWidth) / 2, (getHeight() + textHeight / 2) / 2 + 2); } - }); - buttonPanel.add(btnMedium, gbc); - - // Hard button - JButton btnHard = new JButton("Hard (25x25)"); - btnHard.setFont(new Font("Arial", Font.PLAIN, 16)); - btnHard.setPreferredSize(new Dimension(200, 45)); - btnHard.addActionListener(new ActionListener() { + + @Override + public boolean isContentAreaFilled() { + return false; + } + }; + startButton.setFont(new Font("Segoe UI", Font.BOLD, 18)); + startButton.setPreferredSize(new Dimension(300, 50)); + startButton.setFocusPainted(false); + startButton.setBorderPainted(false); + startButton.setContentAreaFilled(false); + startButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - startGame(HARD_ROWS, HARD_COLUMNS, HARD_MINES); + startGameWithSelectedDifficulty(); } }); - buttonPanel.add(btnHard, gbc); + gbc.insets = new Insets(0, 0, 0, 0); + cardPanel.add(startButton, gbc); + + // Add hint label + JLabel hintLabel = new JLabel("Tip: Left-click to reveal, Right-click to flag", JLabel.CENTER); + hintLabel.setFont(new Font("Segoe UI", Font.ITALIC, 12)); + hintLabel.setForeground(TEXT_LIGHT_COLOR); + gbc.insets = new Insets(20, 0, 0, 0); + cardPanel.add(hintLabel, gbc); + + // Wrap card panel in a container with shadow effect + JPanel cardContainer = new JPanel(new BorderLayout()); + cardContainer.setOpaque(false); + cardContainer.setBorder(BorderFactory.createEmptyBorder(0, 30, 30, 30)); + cardContainer.add(cardPanel, BorderLayout.CENTER); - mainPanel.add(buttonPanel, BorderLayout.CENTER); + mainPanel.add(cardContainer, BorderLayout.CENTER); add(mainPanel); setVisible(true); } + /** + * Start the game with selected difficulty + */ + private void startGameWithSelectedDifficulty() { + int selectedIndex = difficultyComboBox.getSelectedIndex(); + int rows, columns, minesNum; + + switch (selectedIndex) { + case 0: // Easy + rows = EASY_ROWS; + columns = EASY_COLUMNS; + minesNum = EASY_MINES; + break; + case 1: // Medium + rows = MEDIUM_ROWS; + columns = MEDIUM_COLUMNS; + minesNum = MEDIUM_MINES; + break; + case 2: // Hard + rows = HARD_ROWS; + columns = HARD_COLUMNS; + minesNum = HARD_MINES; + break; + default: // Default to Easy + rows = EASY_ROWS; + columns = EASY_COLUMNS; + minesNum = EASY_MINES; + } + + startGame(rows, columns, minesNum); + } + /** * Start the game with specified difficulty * @param rows number of rows @@ -112,7 +309,29 @@ private void startGame(int rows, int columns, int minesNum) { new MinesFrame(rows, columns, minesNum); } + /** + * Set the default UI font for all components + * @param font the font to set + */ + private static void setUIFont(FontUIResource font) { + java.util.Enumeration keys = UIManager.getDefaults().keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + Object value = UIManager.get(key); + if (value instanceof FontUIResource) { + UIManager.put(key, font); + } + } + } + public static void main(String[] args) { + // Use system look and feel for better integration + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + new StartFrame(); } }