2016-07-10 4 views
1

Я смотрю на этот пример Using Swing Components; Examples. Этот пример показывает JTabbedPane с пользовательским компонентом вкладки, который имеет кнопку закрытия на каждой вкладке.JTabbedPane настраиваемый компонентный макет

Если JTabbedPane находится в WRAP_TAB_LAYOUT, заголовок вкладки и кнопка закрытия находятся в середине широкой вкладки. Как изменить этот пример, что заголовок вкладки все еще будет отображаться в центре вкладки, но кнопка закрытия появится рядом с правой границей вкладок?

Вот картина:

enter image description here

+0

это управляется Look & Feel. – trashgod

ответ

1
  • Вот одна из возможных реализаций с использованием UIManager.put("TabbedPane.tabInsets", insets) и JLayer
    • Paint кнопку закрытия на внутреннем крае вкладки с помощью JLayer
    • Я не тестировал на NumbusLookAndFeel

enter image description here

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))); 
    } 
    } 
}