diff --git a/src/dev/kske/chess/ui/GameTabComponent.java b/src/dev/kske/chess/ui/GameTabComponent.java new file mode 100644 index 0000000..ff492b4 --- /dev/null +++ b/src/dev/kske/chess/ui/GameTabComponent.java @@ -0,0 +1,99 @@ +package dev.kske.chess.ui; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.plaf.basic.BasicButtonUI; + +/** + * Project: Chess
+ * File: GameTabComponent.java
+ * Created: 11 Dec 2019
+ * + * @author Kai S. K. Engelbart + */ +public class GameTabComponent extends JPanel { + + private final JTabbedPane tabbedPane; + + private static final long serialVersionUID = 9022979950018125935L; + + public GameTabComponent(JTabbedPane tabbedPane) { + super(new FlowLayout(FlowLayout.LEFT, 0, 0)); + if (tabbedPane == null) throw new NullPointerException("TabbedPane is null"); + this.tabbedPane = tabbedPane; + + // Create title JLabel + JLabel label = new JLabel() { + + private static final long serialVersionUID = 7902391411509551586L; + + @Override + public String getText() { + int i = tabbedPane.indexOfTabComponent(GameTabComponent.this); + return i != -1 ? tabbedPane.getTitleAt(i) : ""; + } + }; + label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + add(label); + + // Create close JButton + add(new TabButton()); + setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); + } + + private class TabButton extends JButton { + + private static final long serialVersionUID = -2757857832337636731L; + + public TabButton() { + final int size = 17; + setPreferredSize(new Dimension(size, size)); + setToolTipText("Close this tab"); + setUI(new BasicButtonUI()); + setContentAreaFilled(false); + setFocusable(false); + setBorder(BorderFactory.createEtchedBorder()); + setBorderPainted(false); + addMouseListener(new MouseAdapter() { + + @Override + public void mouseEntered(MouseEvent evt) { setBorderPainted(true); } + + @Override + public void mouseExited(MouseEvent evt) { setBorderPainted(false); } + }); + setRolloverEnabled(true); + addActionListener((evt) -> { int i = tabbedPane.indexOfTabComponent(GameTabComponent.this); if (i != -1) tabbedPane.remove(i); }); + } + + @Override + public void updateUI() {} + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g.create(); + // shift the image for pressed buttons + if (getModel().isPressed()) { g2.translate(1, 1); } + g2.setStroke(new BasicStroke(2)); + g2.setColor(Color.BLACK); + if (getModel().isRollover()) { g2.setColor(Color.MAGENTA); } + final int delta = 6; + g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1); + g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1); + g2.dispose(); + } + } +} diff --git a/src/dev/kske/chess/ui/MainWindow.java b/src/dev/kske/chess/ui/MainWindow.java index 3dc54b5..22ccbc3 100644 --- a/src/dev/kske/chess/ui/MainWindow.java +++ b/src/dev/kske/chess/ui/MainWindow.java @@ -26,7 +26,7 @@ import dev.kske.chess.pgn.PGNGame; * Project: Chess
* File: MainWindow.java
* Created: 01.07.2019
- * + * * @since Chess v0.1-alpha * @author Kai S. K. Engelbart */ @@ -88,21 +88,22 @@ public class MainWindow extends JFrame { /** * Creates a new {@link GamePane}, adds it to the tabbed pane and opens it. * The new tab has the title {@code Game n} where {@code n} is its number. - * + * * @return The new {@link GamePane} */ - public GamePane addGamePane() { return addGamePane("Game " + (tabbedPane.getComponentCount() + 1)); } + public GamePane addGamePane() { return addGamePane("Game " + (tabbedPane.getTabCount() + 1)); } /** * Creates a new {@link GamePane}, adds it to the tabbed pane and opens it. - * + * * @param title The title of the {@link GamePane} * @return The new {@link GamePane} */ public GamePane addGamePane(String title) { GamePane gamePane = new GamePane(); tabbedPane.add(title, gamePane); - tabbedPane.setSelectedIndex(tabbedPane.getComponentCount() - 1); + tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new GameTabComponent(tabbedPane)); + tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1); return gamePane; } @@ -119,14 +120,14 @@ public class MainWindow extends JFrame { /** * Removes a {@link GamePane} form the tabbed pane. - * + * * @param index The index of the {@link GamePane} to remove */ public void removeGamePane(int index) { tabbedPane.remove(index); } /** * Loads a game file (FEN or PGN) and adds it to a new {@link GamePane}. - * + * * @param files the files to load the game from */ public void loadFiles(List files) {