2011-10-22 16 views
8

Tôi muốn tùy chỉnh giao diện của các tab trong JTabbedPane.
Tôi muốn bắt đầu từ hành vi đơn giản và đơn giản nhất: không có viền, màu đồng nhất.
Vấn đề là một sự không đồng đều vẫn còn: các tab lề nhỏ chồng lên nhau.
JTabbedPane tùy chỉnh giao diện tab

enter image description here

Bạn thấy rằng kể từ tab thứ hai được chọn, nó được "đưa đến fore". Điều này đạt được bằng một lề nhỏ chồng lên nhau. Có cách nào (không phức tạp) để vô hiệu hóa hành vi này không?

đơn giản, kiểm chứng (chỉ sửa chữa hàng nhập khẩu) mã:

public class TabbedPane_LookStudy extends JFrame{ 

public static void main(String [] args) throws UnsupportedLookAndFeelException { 
    UIManager.setLookAndFeel(new NimbusLookAndFeel()); 
    new TabbedPane_LookStudy().setVisible(true); 
} 

public TabbedPane_LookStudy() { 
    JTabbedPane tp = new JTabbedPane(); 
    tp.setUI(new MyTabbedPaneUI()); 
    add(tp); 

    tp.addTab("first",new JPanel()); 
    tp.addTab("second", new JPanel()); 
    tp.addTab("third", new JPanel()); 

    setPreferredSize(new Dimension(180,100)); 
    pack(); 
} 

public static class MyTabbedPaneUI extends javax.swing.plaf.basic.BasicTabbedPaneUI { 

    @Override 
    protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, 
       int tabIndex, Rectangle iconRect, Rectangle textRect) { 
     Color savedColor = g.getColor(); 
     g.setColor(Color.PINK); 
     g.fillRect(rects[tabIndex].x, rects[tabIndex].y, 
       rects[tabIndex].width, rects[tabIndex].height); 
     g.setColor(Color.BLUE); 
     g.drawRect(rects[tabIndex].x, rects[tabIndex].y, 
       rects[tabIndex].width, rects[tabIndex].height); 
     g.setColor(savedColor); 
    } 
} 

}

+0

+1 hình ảnh, sscce, câu hỏi – mKorbel

Trả lời

4

cách chính xác sẽ được thực hiện Custom Look & Feel chỉ. Nhưng nếu bạn muốn chơi với XxxTabbedPaneUI, thì có thể this post có thể giúp bạn với điều đó.

cho Nimbus sẽ được tốt hơn để kiểm tra aephyr đang kho

+0

tôi bắt đầu từ bài đó. Nhưng trong quá trình triển khai giao diện người dùng đó, chỉ có các phương thức paintXXX và vị trí tab calculateTabWidth và calculateTabHeight và NOT.Vì vậy, tôi nghĩ rằng logic vị trí tab phải được chứa ở nơi khác. – AgostinoX

+0

'Vị trí tab KHÔNG' của bạn là gì, bạn có thể vẽ nó từ Biên giới trên cùng ... đến dưới cùng, Tab Pacement nằm ở trên cùng? – mKorbel

+0

xin lỗi, mKorbel, tôi không hiểu. bạn có thể diễn giải? – AgostinoX

1

Bạn có thể ghi đè lên paintContentBorderTopEdge trong MyTabbedPaneUI để nó không nghĩ bất kỳ của các tab đang được chọn. Đây không phải là một giải pháp tuyệt vời, nhưng việc hack các lớp UI hiếm khi tự mượn cho một trong những trải nghiệm của tôi :)

@Override 
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, 
         int selectedIndex, int x, int y, int w, int h) { 
    super.paintContentBorderTopEdge(g, tabPlacement, -1, x, y, w, h); 
} 
2

Giải pháp đầu tiên (một phần). Tôi đã định vị mã "định vị".
Đây là phương thức calculateTabRects trong TabbedPaneLayout, một lớp bên trong của BasicTabbedPaneUI. Phương pháp này cực kỳ phức tạp, nhưng điều tốt đẹp mới là phần "tăng lên trước" tab cũng được nhận xét và được cách ly theo phương pháp riêng của nó! Đó là padSelectedTab.

Tạo một lớp mà không làm gì thay vì huy động các thành phần cũng đơn giản như:

protected class MyTabbedPaneLayout extends TabbedPaneLayout { 
     @Override 
     protected void padSelectedTab(int tabPlacement, int selectedIndex) { 
      //do nothing! 
      //super.padSelectedTab(tabPlacement, selectedIndex); 
     } 
    } 

Chú ý rằng đó phải là một lớp bên trong của MyTabbedPane. Nó phải được khởi tạo bằng cách ghi đè MyTabbedPane.createLayoutManager:

@Override 
    protected LayoutManager createLayoutManager() { 
     //return super.createLayoutManager(); 
     return new MyTabbedPaneLayout(); 
    } 

Rất dễ dàng và thực sự làm việc ... trừ trường hợp. Trình tạo createLayoutManager khởi tạo TabbedPaneLayout nếu tabLayoutPolicy là WRAP_TAB_LAYOUT, nhưng instantiates TabbedPanelScrollLayout nếu tabLayoutPolicy là SCROLL_TAB_LAYOUT. Sau này có riêng và không được bảo vệ quyền truy cập, vì vậy không thể phân lớp được!
Hàm implition createLayoutManager của tôi làm mất hoạt động cuộn.

1

Bạn có thể đặt thẻ Html vào tham số đầu tiên như sau:

MyJTabbedPane.addTab("<html><h1 style='padding:20px;'>TEST</h1></html>", new JPanel());