Reputation: 805
I'm looking at this example Using Swing Components; Examples. This example shows JTabbedPane
with custom tab component which has close button in each tab.
If JTabbedPane is in WRAP_TAB_LAYOUT
the tab title and the close button is in the middle of the wide tab. How to change this example that the tab title still would be visible in the center of the tab, but the close button would appear next to right tab border?
Here is a picture:
Upvotes: 1
Views: 579
Reputation: 9808
UIManager.put("TabbedPane.tabInsets", insets)
and JLayer
JLayer
NumbusLookAndFeel
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class RightCloseTabButtonTest {
public JComponent makeUI() {
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Tab 1", new JLabel("aaa"));
tabs.addTab("Tab 2", new JLabel("bbb"));
tabs.addTab("Tab 3", new JLabel("ccc"));
tabs.addTab("Tab 4", new JLabel("ddd"));
return new JLayer<JTabbedPane>(tabs, new CloseableTabbedPaneLayerUI());
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
UIManager.put("TabbedPane.tabInsets", new Insets(2, 2 + 16, 2, 2 + 16));
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new RightCloseTabButtonTest().makeUI());
f.setSize(300, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class CloseTabIcon implements Icon {
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(x, y);
g2.setPaint(Color.BLACK);
if (c instanceof AbstractButton) {
ButtonModel m = ((AbstractButton) c).getModel();
if (m.isRollover()) {
g2.setPaint(Color.ORANGE);
}
}
g2.drawLine(4, 4, 11, 11);
g2.drawLine(4, 5, 10, 11);
g2.drawLine(5, 4, 11, 10);
g2.drawLine(11, 4, 4, 11);
g2.drawLine(11, 5, 5, 11);
g2.drawLine(10, 4, 4, 10);
g2.dispose();
}
@Override public int getIconWidth() {
return 16;
}
@Override public int getIconHeight() {
return 16;
}
}
class CloseableTabbedPaneLayerUI extends LayerUI<JTabbedPane> {
private final JComponent rubberStamp = new JPanel();
private final Point pt = new Point();
private final JButton button = new JButton(new CloseTabIcon()) {
@Override public void updateUI() {
super.updateUI();
setBorder(BorderFactory.createEmptyBorder());
setFocusPainted(false);
setBorderPainted(false);
setContentAreaFilled(false);
setRolloverEnabled(false);
}
};
@Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof JLayer) {
JLayer jlayer = (JLayer) c;
JTabbedPane tabPane = (JTabbedPane) jlayer.getView();
Dimension d = button.getPreferredSize();
for (int i = 0; i < tabPane.getTabCount(); i++) {
Rectangle rect = tabPane.getBoundsAt(i);
int x = rect.x + rect.width - d.width - 2;
int y = rect.y + (rect.height - d.height) / 2;
Rectangle r = new Rectangle(x, y, d.width, d.height);
button.getModel().setRollover(r.contains(pt));
SwingUtilities.paintComponent(g, button, rubberStamp, r);
}
}
}
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processMouseEvent(
MouseEvent e, JLayer<? extends JTabbedPane> l) {
if (e.getID() == MouseEvent.MOUSE_CLICKED) {
pt.setLocation(e.getPoint());
JTabbedPane tabbedPane = (JTabbedPane) l.getView();
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
Rectangle rect = tabbedPane.getBoundsAt(index);
Dimension d = button.getPreferredSize();
int x = rect.x + rect.width - d.width - 2;
int y = rect.y + (rect.height - d.height) / 2;
Rectangle r = new Rectangle(x, y, d.width, d.height);
if (r.contains(pt)) {
tabbedPane.removeTabAt(index);
}
}
}
}
@Override protected void processMouseMotionEvent(
MouseEvent e, JLayer<? extends JTabbedPane> l) {
pt.setLocation(e.getPoint());
JTabbedPane t = (JTabbedPane) l.getView();
if (t.indexAtLocation(pt.x, pt.y) >= 0) {
Point loc = e.getPoint();
loc.translate(-16, -16);
l.repaint(new Rectangle(loc, new Dimension(32, 32)));
}
}
}
Upvotes: 1