我正在看这个例子Using Swing Components; Examples。此示例显示JTabbedPane
带有自定义标签组件,每个标签中都有关闭按钮。
如果JTabbedPane位于WRAP_TAB_LAYOUT
标签标题中,则关闭按钮位于宽标签的中间。如何更改此选项卡选项卡中心仍然可以看到选项卡标题,但关闭按钮会出现在右侧选项卡边框旁边?
这是一张图片:
答案 0 :(得分:1)
UIManager.put("TabbedPane.tabInsets", insets)
和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)));
}
}
}