Implementing a closing button for game pane tabs #17
99
src/dev/kske/chess/ui/GameTabComponent.java
Normal file
99
src/dev/kske/chess/ui/GameTabComponent.java
Normal file
@ -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: <strong>Chess</strong><br>
|
||||||
|
* File: <strong>GameTabComponent.java</strong><br>
|
||||||
|
* Created: <strong>11 Dec 2019</strong><br>
|
||||||
|
*
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,7 @@ import dev.kske.chess.pgn.PGNGame;
|
|||||||
* Project: <strong>Chess</strong><br>
|
* Project: <strong>Chess</strong><br>
|
||||||
* File: <strong>MainWindow.java</strong><br>
|
* File: <strong>MainWindow.java</strong><br>
|
||||||
* Created: <strong>01.07.2019</strong><br>
|
* Created: <strong>01.07.2019</strong><br>
|
||||||
*
|
*
|
||||||
* @since Chess v0.1-alpha
|
* @since Chess v0.1-alpha
|
||||||
* @author Kai S. K. Engelbart
|
* @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.
|
* 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.
|
* The new tab has the title {@code Game n} where {@code n} is its number.
|
||||||
*
|
*
|
||||||
* @return The new {@link GamePane}
|
* @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.
|
* Creates a new {@link GamePane}, adds it to the tabbed pane and opens it.
|
||||||
*
|
*
|
||||||
* @param title The title of the {@link GamePane}
|
* @param title The title of the {@link GamePane}
|
||||||
* @return The new {@link GamePane}
|
* @return The new {@link GamePane}
|
||||||
*/
|
*/
|
||||||
public GamePane addGamePane(String title) {
|
public GamePane addGamePane(String title) {
|
||||||
GamePane gamePane = new GamePane();
|
GamePane gamePane = new GamePane();
|
||||||
tabbedPane.add(title, 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;
|
return gamePane;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,14 +120,14 @@ public class MainWindow extends JFrame {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a {@link GamePane} form the tabbed pane.
|
* Removes a {@link GamePane} form the tabbed pane.
|
||||||
*
|
*
|
||||||
* @param index The index of the {@link GamePane} to remove
|
* @param index The index of the {@link GamePane} to remove
|
||||||
*/
|
*/
|
||||||
public void removeGamePane(int index) { tabbedPane.remove(index); }
|
public void removeGamePane(int index) { tabbedPane.remove(index); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a game file (FEN or PGN) and adds it to a new {@link GamePane}.
|
* Loads a game file (FEN or PGN) and adds it to a new {@link GamePane}.
|
||||||
*
|
*
|
||||||
* @param files the files to load the game from
|
* @param files the files to load the game from
|
||||||
*/
|
*/
|
||||||
public void loadFiles(List<File> files) {
|
public void loadFiles(List<File> files) {
|
||||||
|
Reference in New Issue
Block a user