yo
This commit is contained in:
@@ -1,41 +1,509 @@
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class TwoPlayerGameDriver
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
JFrame frame = new JFrame();
|
||||
frame.setTitle("Two Player Game");
|
||||
/**
|
||||
* GameDriver — application entry point.
|
||||
*
|
||||
* <p>Owns the JFrame and the root CardLayout container. All UI screens (name entry, main menu,
|
||||
* credits) live here as static inner classes so the project stays at four .java files.
|
||||
*
|
||||
* <p>Card keys: "NAMES" — JTextField name-entry screen (shown first) "MENU" — level-select /
|
||||
* difficulty screen "LEVEL1" — in-game (all three share one GamePanel instance) "LEVEL2" "LEVEL3"
|
||||
* "CREDITS" — scrolling JList credits, added on demand
|
||||
*/
|
||||
public class TwoPlayerGameDriver {
|
||||
|
||||
// CardLayout
|
||||
CardLayout layout = new CardLayout();
|
||||
JPanel container = new JPanel(layout);
|
||||
public static void main(String[] args) {
|
||||
SwingUtilities.invokeLater(
|
||||
() -> {
|
||||
JFrame frame = new JFrame("Two Player Game");
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.setResizable(false);
|
||||
|
||||
//Panels
|
||||
GameFields gamePanel = new GameFields();
|
||||
LvlManager levelMenu = new LvlManager(gamePanel);
|
||||
MainMenu menuPanel = new MainMenu(gamePanel);
|
||||
CardLayout layout = new CardLayout();
|
||||
JPanel container = new JPanel(layout);
|
||||
|
||||
//add to cardLayout
|
||||
container.add(menuPanel, "MENU"); //+ more
|
||||
container.add(levelMenu, "LEVELS");
|
||||
container.add(gamePanel, "GAME");
|
||||
// One shared GamePanel — added under all three level keys
|
||||
GamePanel gamePanel = new GamePanel();
|
||||
container.add(gamePanel, "LEVEL1");
|
||||
container.add(gamePanel, "LEVEL2");
|
||||
container.add(gamePanel, "LEVEL3");
|
||||
|
||||
//switch screens
|
||||
menuPanel.setContainer(container,layout); //+ more
|
||||
levelMenu.setContainer(container,layout);
|
||||
gamePanel.setContainer(container,layout);
|
||||
// Main menu (level-select)
|
||||
MainMenu menu = new MainMenu(gamePanel);
|
||||
container.add(menu, "MENU");
|
||||
|
||||
frame.add(container);
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
//gamePanel.requestFocus();
|
||||
frame.setVisible(true);
|
||||
// Name-entry screen — shown first on launch
|
||||
NameEntry nameEntry = new NameEntry(gamePanel, menu);
|
||||
container.add(nameEntry, "NAMES");
|
||||
|
||||
//frame
|
||||
frame.setResizable(false);
|
||||
frame.setSize(640, 360); //<-- change later
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
// Wire container + layout into every screen that needs to navigate
|
||||
gamePanel.setContainer(container, layout);
|
||||
menu.setContainer(container, layout);
|
||||
nameEntry.setContainer(container, layout);
|
||||
|
||||
frame.add(container);
|
||||
frame.pack();
|
||||
frame.setSize(640, 360);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
|
||||
// Start on the name-entry screen
|
||||
layout.show(container, "NAMES");
|
||||
});
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// NameEntry — JTextField-based screen that captures player names
|
||||
//
|
||||
// Rubric: "Input text box — players name input"
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
static class NameEntry extends JPanel {
|
||||
|
||||
private JPanel container;
|
||||
private CardLayout cardLayout;
|
||||
|
||||
private final JTextField field1 = new JTextField("Player 1", 14);
|
||||
private final JTextField field2 = new JTextField("Player 2", 14);
|
||||
|
||||
NameEntry(GamePanel gp, MainMenu menu) {
|
||||
setLayout(null);
|
||||
setPreferredSize(new Dimension(640, 360));
|
||||
setOpaque(false);
|
||||
|
||||
// Title
|
||||
JLabel title = new JLabel("ENTER PLAYER NAMES", SwingConstants.CENTER);
|
||||
title.setFont(new Font("Arial", Font.BOLD, 26));
|
||||
title.setForeground(Color.WHITE);
|
||||
title.setBounds(0, 40, 640, 40);
|
||||
add(title);
|
||||
|
||||
// Sub-labels
|
||||
JLabel lbl1 = new JLabel("Bear Player (Arrow Keys):", SwingConstants.RIGHT);
|
||||
lbl1.setForeground(new Color(210, 140, 60));
|
||||
lbl1.setFont(new Font("Arial", Font.BOLD, 14));
|
||||
lbl1.setBounds(80, 130, 220, 30);
|
||||
add(lbl1);
|
||||
|
||||
JLabel lbl2 = new JLabel("Seal Player (WASD):", SwingConstants.RIGHT);
|
||||
lbl2.setForeground(new Color(70, 160, 220));
|
||||
lbl2.setFont(new Font("Arial", Font.BOLD, 14));
|
||||
lbl2.setBounds(80, 185, 220, 30);
|
||||
add(lbl2);
|
||||
|
||||
// Text fields — select-all on focus for easy overtype
|
||||
styleField(field1, new Color(210, 140, 60));
|
||||
styleField(field2, new Color(70, 160, 220));
|
||||
field1.setBounds(315, 130, 200, 30);
|
||||
field2.setBounds(315, 185, 200, 30);
|
||||
add(field1);
|
||||
add(field2);
|
||||
|
||||
// Confirm button — saves names to GamePanel & GameDriver shared state,
|
||||
// then flips to the menu
|
||||
JButton confirm = new JButton("CONTINUE →");
|
||||
confirm.setFont(new Font("Arial", Font.BOLD, 14));
|
||||
confirm.setForeground(Color.WHITE);
|
||||
confirm.setBackground(new Color(30, 80, 30));
|
||||
confirm.setBorder(BorderFactory.createLineBorder(new Color(80, 200, 80), 2));
|
||||
confirm.setFocusPainted(false);
|
||||
confirm.setBounds(220, 255, 200, 36);
|
||||
add(confirm);
|
||||
|
||||
ActionListener go =
|
||||
e -> {
|
||||
String n1 = field1.getText().trim();
|
||||
String n2 = field2.getText().trim();
|
||||
if (n1.isEmpty()) n1 = "Bear";
|
||||
if (n2.isEmpty()) n2 = "Seal";
|
||||
// Push names to GamePanel so startLevel() picks them up
|
||||
gp.bear.name = n1;
|
||||
gp.seal.name = n2;
|
||||
// Also give MainMenu a reference so its buttons can pass them through
|
||||
menu.pendingName1 = n1;
|
||||
menu.pendingName2 = n2;
|
||||
cardLayout.show(container, "MENU");
|
||||
};
|
||||
|
||||
confirm.addActionListener(go);
|
||||
// Pressing Enter in either field also confirms
|
||||
field1.addActionListener(go);
|
||||
field2.addActionListener(go);
|
||||
|
||||
// Instruction hint
|
||||
JLabel hint = new JLabel("Press Enter or click Continue", SwingConstants.CENTER);
|
||||
hint.setForeground(Color.GRAY);
|
||||
hint.setFont(new Font("Arial", Font.ITALIC, 11));
|
||||
hint.setBounds(0, 305, 640, 20);
|
||||
add(hint);
|
||||
}
|
||||
}
|
||||
|
||||
void setContainer(JPanel c, CardLayout cl) {
|
||||
container = c;
|
||||
cardLayout = cl;
|
||||
}
|
||||
|
||||
private void styleField(JTextField f, Color accent) {
|
||||
f.setFont(new Font("Arial", Font.PLAIN, 14));
|
||||
f.setBackground(new Color(30, 30, 55));
|
||||
f.setForeground(accent);
|
||||
f.setCaretColor(Color.WHITE);
|
||||
f.setBorder(
|
||||
BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createLineBorder(accent, 2),
|
||||
BorderFactory.createEmptyBorder(2, 6, 2, 6)));
|
||||
f.addFocusListener(
|
||||
new FocusAdapter() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
f.selectAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.setPaint(
|
||||
new GradientPaint(0, 0, new Color(10, 10, 30), 0, getHeight(), new Color(20, 10, 40)));
|
||||
g2.fillRect(0, 0, getWidth(), getHeight());
|
||||
super.paintComponent(g);
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// MainMenu — level-select, difficulty chooser, speed slider, quit
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
static class MainMenu extends JPanel {
|
||||
|
||||
private JPanel container;
|
||||
private CardLayout cardLayout;
|
||||
|
||||
// Names supplied by NameEntry before the menu is shown
|
||||
String pendingName1 = "Bear";
|
||||
String pendingName2 = "Seal";
|
||||
|
||||
MainMenu(GamePanel gp) {
|
||||
setLayout(null);
|
||||
setPreferredSize(new Dimension(640, 360));
|
||||
setOpaque(false);
|
||||
|
||||
// Title
|
||||
JLabel title = new JLabel("SELECT A LEVEL", SwingConstants.CENTER);
|
||||
title.setFont(new Font("Arial", Font.BOLD, 26));
|
||||
title.setForeground(Color.WHITE);
|
||||
title.setBounds(0, 18, 640, 36);
|
||||
add(title);
|
||||
|
||||
// "Change names" link back to name entry
|
||||
JButton changeName = new JButton("← Change Names");
|
||||
changeName.setFont(new Font("Arial", Font.PLAIN, 11));
|
||||
changeName.setForeground(Color.LIGHT_GRAY);
|
||||
changeName.setContentAreaFilled(false);
|
||||
changeName.setBorderPainted(false);
|
||||
changeName.setFocusPainted(false);
|
||||
changeName.setBounds(10, 10, 140, 22);
|
||||
add(changeName);
|
||||
changeName.addActionListener(e -> cardLayout.show(container, "NAMES"));
|
||||
|
||||
// Level buttons
|
||||
LevelButton lvl1 =
|
||||
new LevelButton(1, "The Crossing", new Color(40, 100, 110), new Color(0, 200, 220));
|
||||
LevelButton lvl2 =
|
||||
new LevelButton(2, "Double Danger", new Color(120, 70, 20), new Color(255, 150, 0));
|
||||
LevelButton lvl3 =
|
||||
new LevelButton(3, "The Gauntlet", new Color(110, 20, 20), new Color(255, 60, 60));
|
||||
|
||||
lvl1.setBounds(80, 90, 160, 160);
|
||||
lvl2.setBounds(240, 90, 160, 160);
|
||||
lvl3.setBounds(400, 90, 160, 160);
|
||||
add(lvl1);
|
||||
add(lvl2);
|
||||
add(lvl3);
|
||||
|
||||
lvl1.addActionListener(e -> gp.startLevel(pendingName1, pendingName2, "LEVEL1"));
|
||||
lvl2.addActionListener(e -> gp.startLevel(pendingName1, pendingName2, "LEVEL2"));
|
||||
lvl3.addActionListener(e -> gp.startLevel(pendingName1, pendingName2, "LEVEL3"));
|
||||
|
||||
// Difficulty radio buttons
|
||||
JRadioButton easy = new JRadioButton("Easy", true);
|
||||
JRadioButton medium = new JRadioButton("Medium");
|
||||
JRadioButton hard = new JRadioButton("Hard");
|
||||
ButtonGroup grp = new ButtonGroup();
|
||||
for (JRadioButton rb : new JRadioButton[] {easy, medium, hard}) {
|
||||
rb.setForeground(Color.WHITE);
|
||||
rb.setOpaque(false);
|
||||
grp.add(rb);
|
||||
}
|
||||
easy.addActionListener(e -> gp.setDifficulty("Easy"));
|
||||
medium.addActionListener(e -> gp.setDifficulty("Medium"));
|
||||
hard.addActionListener(e -> gp.setDifficulty("Hard"));
|
||||
|
||||
JLabel diffLabel = new JLabel("Difficulty:");
|
||||
diffLabel.setForeground(Color.LIGHT_GRAY);
|
||||
JPanel diff = new JPanel(new FlowLayout(FlowLayout.CENTER, 8, 0));
|
||||
diff.setOpaque(false);
|
||||
diff.add(diffLabel);
|
||||
diff.add(easy);
|
||||
diff.add(medium);
|
||||
diff.add(hard);
|
||||
diff.setBounds(140, 268, 360, 26);
|
||||
add(diff);
|
||||
|
||||
// Quit → rolling credits → System.exit
|
||||
JButton quit = new JButton("QUIT");
|
||||
quit.setFont(new Font("Arial", Font.BOLD, 12));
|
||||
quit.setForeground(Color.WHITE);
|
||||
quit.setBackground(new Color(80, 20, 20));
|
||||
quit.setBorder(BorderFactory.createLineBorder(new Color(180, 60, 60), 2));
|
||||
quit.setFocusPainted(false);
|
||||
quit.setBounds(275, 58, 90, 26);
|
||||
add(quit);
|
||||
quit.addActionListener(e -> showCredits());
|
||||
}
|
||||
|
||||
void setContainer(JPanel c, CardLayout cl) {
|
||||
container = c;
|
||||
cardLayout = cl;
|
||||
}
|
||||
|
||||
private void showCredits() {
|
||||
String[] lines = {
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"~ CREDITS ~",
|
||||
"",
|
||||
"Developed by:",
|
||||
"Aimee Azzahra",
|
||||
"Ayan Mishra",
|
||||
"Jennifer Phan",
|
||||
"",
|
||||
"Character Art — Jennifer Phan",
|
||||
"Background Art — Aimee Azzahra",
|
||||
"",
|
||||
"Programming:",
|
||||
"Jennifer — Player object, fluid logic, float method",
|
||||
"Aimee — Wall/Rock collision, TileSet class, tap method",
|
||||
"Ayan — Main menu, level manager, hold method",
|
||||
"",
|
||||
"Thanks for playing!",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
};
|
||||
CreditsPanel credits = new CreditsPanel(lines, () -> System.exit(0));
|
||||
container.add(credits, "CREDITS");
|
||||
cardLayout.show(container, "CREDITS");
|
||||
credits.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2 = (Graphics2D) g;
|
||||
g2.setPaint(
|
||||
new GradientPaint(0, 0, new Color(10, 10, 30), 0, getHeight(), new Color(30, 10, 50)));
|
||||
g2.fillRect(0, 0, getWidth(), getHeight());
|
||||
super.paintComponent(g);
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// LevelButton — rollover icon changes dramatically (rubric item)
|
||||
// Normal : small muted rounded tile + level number
|
||||
// Hover : large bright tile with glow rings, big number, stars
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
private static class LevelButton extends JButton {
|
||||
|
||||
private static final int CANVAS = 140;
|
||||
private static final int TILE_NORM = 76;
|
||||
private static final int TILE_HOV = 112;
|
||||
|
||||
private final int level;
|
||||
private final String levelName;
|
||||
private final Color tileColor;
|
||||
private final Color hoverColor;
|
||||
private boolean hovered = false;
|
||||
|
||||
LevelButton(int level, String levelName, Color tile, Color hover) {
|
||||
this.level = level;
|
||||
this.levelName = levelName;
|
||||
this.tileColor = tile;
|
||||
this.hoverColor = hover;
|
||||
|
||||
setContentAreaFilled(false);
|
||||
setBorderPainted(false);
|
||||
setFocusPainted(false);
|
||||
setOpaque(false);
|
||||
setIcon(buildIcon(false));
|
||||
setRolloverEnabled(true);
|
||||
setRolloverIcon(buildIcon(true));
|
||||
setPreferredSize(new Dimension(160, 160));
|
||||
setSize(160, 160);
|
||||
setVerticalTextPosition(SwingConstants.BOTTOM);
|
||||
setHorizontalTextPosition(SwingConstants.CENTER);
|
||||
setFont(new Font("Arial", Font.BOLD, 12));
|
||||
setForeground(Color.WHITE);
|
||||
|
||||
addMouseListener(
|
||||
new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
hovered = true;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
hovered = false;
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
String label = hovered ? levelName : "Level " + level;
|
||||
Color fg = hovered ? hoverColor.brighter().brighter() : Color.LIGHT_GRAY;
|
||||
FontMetrics fm = g2.getFontMetrics(getFont());
|
||||
int tx = (getWidth() - fm.stringWidth(label)) / 2;
|
||||
int ty = getHeight() - 6;
|
||||
g2.setFont(getFont());
|
||||
g2.setColor(Color.BLACK);
|
||||
g2.drawString(label, tx + 1, ty + 1);
|
||||
g2.setColor(fg);
|
||||
g2.drawString(label, tx, ty);
|
||||
g2.dispose();
|
||||
}
|
||||
|
||||
private ImageIcon buildIcon(boolean hover) {
|
||||
BufferedImage img = new BufferedImage(CANVAS, CANVAS, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = img.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
int cx = CANVAS / 2, cy = CANVAS / 2;
|
||||
|
||||
if (hover) {
|
||||
// Concentric glow rings
|
||||
for (int i = 4; i >= 1; i--) {
|
||||
int r = TILE_HOV / 2 + i * 9;
|
||||
g.setColor(
|
||||
new Color(
|
||||
hoverColor.getRed() / 255f,
|
||||
hoverColor.getGreen() / 255f,
|
||||
hoverColor.getBlue() / 255f,
|
||||
0.12f * i));
|
||||
g.fillOval(cx - r, cy - r, r * 2, r * 2);
|
||||
}
|
||||
g.setColor(hoverColor);
|
||||
g.fillRoundRect(cx - TILE_HOV / 2, cy - TILE_HOV / 2, TILE_HOV, TILE_HOV, 24, 24);
|
||||
g.setColor(Color.WHITE);
|
||||
g.setStroke(new BasicStroke(3f));
|
||||
g.drawRoundRect(cx - TILE_HOV / 2, cy - TILE_HOV / 2, TILE_HOV, TILE_HOV, 24, 24);
|
||||
drawNumber(g, cx, cy, 44);
|
||||
drawStars(g, cx + TILE_HOV / 2 - 26, cy - TILE_HOV / 2 + 6, level);
|
||||
} else {
|
||||
g.setColor(tileColor);
|
||||
g.fillRoundRect(cx - TILE_NORM / 2, cy - TILE_NORM / 2, TILE_NORM, TILE_NORM, 16, 16);
|
||||
g.setColor(tileColor.brighter());
|
||||
g.setStroke(new BasicStroke(1.5f));
|
||||
g.drawRoundRect(cx - TILE_NORM / 2, cy - TILE_NORM / 2, TILE_NORM, TILE_NORM, 16, 16);
|
||||
drawNumber(g, cx, cy, 28);
|
||||
drawStars(g, cx + TILE_NORM / 2 - 20, cy - TILE_NORM / 2 + 4, level);
|
||||
}
|
||||
g.dispose();
|
||||
return new ImageIcon(img);
|
||||
}
|
||||
|
||||
private void drawNumber(Graphics2D g, int cx, int cy, int fs) {
|
||||
g.setColor(Color.WHITE);
|
||||
g.setFont(new Font("Arial", Font.BOLD, fs));
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
String num = String.valueOf(level);
|
||||
g.drawString(num, cx - fm.stringWidth(num) / 2, cy + fm.getAscent() / 2 - 2);
|
||||
}
|
||||
|
||||
private void drawStars(Graphics2D g, int x, int y, int count) {
|
||||
g.setColor(new Color(255, 220, 50));
|
||||
for (int i = 0; i < count; i++) drawStar(g, x - i * 13, y, 10);
|
||||
}
|
||||
|
||||
private void drawStar(Graphics2D g, int cx, int cy, int size) {
|
||||
int pts = 5;
|
||||
double or = size / 2.0, ir = or * 0.4;
|
||||
int[] xs = new int[pts * 2], ys = new int[pts * 2];
|
||||
for (int i = 0; i < pts * 2; i++) {
|
||||
double a = Math.PI / pts * i - Math.PI / 2;
|
||||
double r = (i % 2 == 0) ? or : ir;
|
||||
xs[i] = (int) (cx + r * Math.cos(a));
|
||||
ys[i] = (int) (cy + r * Math.sin(a));
|
||||
}
|
||||
g.fillPolygon(xs, ys, pts * 2);
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// CreditsPanel — scrolling JList (rubric item: "Use JList")
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
static class CreditsPanel extends JPanel {
|
||||
|
||||
private final JScrollPane scrollPane;
|
||||
private final Timer scrollTimer;
|
||||
private int scrollPos = 0;
|
||||
|
||||
CreditsPanel(String[] lines, Runnable onComplete) {
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(Color.BLACK);
|
||||
|
||||
JList<String> list = new JList<>(lines);
|
||||
list.setBackground(Color.BLACK);
|
||||
list.setForeground(Color.WHITE);
|
||||
list.setFont(new Font("SansSerif", Font.BOLD, 18));
|
||||
list.setFixedCellHeight(38);
|
||||
((DefaultListCellRenderer) list.getCellRenderer())
|
||||
.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
scrollPane = new JScrollPane(list);
|
||||
scrollPane.setBorder(null);
|
||||
scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0));
|
||||
add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
// Scroll animation — reads scrollPane field safely; no lambda self-reference
|
||||
scrollTimer =
|
||||
new Timer(
|
||||
28,
|
||||
new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JScrollBar bar = scrollPane.getVerticalScrollBar();
|
||||
bar.setValue(++scrollPos);
|
||||
if (scrollPos >= bar.getMaximum() - bar.getVisibleAmount() + 120) {
|
||||
((Timer) e.getSource()).stop();
|
||||
onComplete.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JButton skip = new JButton("SKIP");
|
||||
skip.setFont(new Font("Arial", Font.BOLD, 12));
|
||||
skip.addActionListener(
|
||||
e -> {
|
||||
scrollTimer.stop();
|
||||
onComplete.run();
|
||||
});
|
||||
add(skip, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
void start() {
|
||||
scrollPos = 0;
|
||||
scrollTimer.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user