我有这个带有 JTabbedPane 的 JDialog:
我只想在 JTabbedPane 的右上角添加一个 JLabel,这样我就可以触发一些事件(例如关闭 JDialog)。而且我不想让它成为一个JFrame。
PS:我知道这可能是重复的,但没有一个回复给我一个解决方案。
我有这个带有 JTabbedPane 的 JDialog:
我只想在 JTabbedPane 的右上角添加一个 JLabel,这样我就可以触发一些事件(例如关闭 JDialog)。而且我不想让它成为一个JFrame。
PS:我知道这可能是重复的,但没有一个回复给我一个解决方案。
好吧,实际上在 Swing 中不支持在 JTabbedPane 内定位。但是你总是可以用布局和图层制作一些街头魔术:
public static void main ( String[] args )
{
try
{
UIManager.setLookAndFeel ( UIManager.getSystemLookAndFeelClassName () );
}
catch ( Throwable e )
{
e.printStackTrace ();
}
JFrame frame = new JFrame ();
frame.setUndecorated ( true );
frame.setLayout ( new LayoutManager ()
{
private List<Component> special = new ArrayList<Component> ();
public void addLayoutComponent ( String name, Component comp )
{
if ( name != null )
{
special.add ( comp );
}
}
public void removeLayoutComponent ( Component comp )
{
special.remove ( comp );
}
public Dimension preferredLayoutSize ( Container parent )
{
Dimension ps = new Dimension ();
for ( Component component : parent.getComponents () )
{
if ( !special.contains ( component ) )
{
Dimension cps = component.getPreferredSize ();
ps.width = Math.max ( ps.width, cps.width );
ps.height = Math.max ( ps.height, cps.height );
}
}
return ps;
}
public Dimension minimumLayoutSize ( Container parent )
{
return preferredLayoutSize ( parent );
}
public void layoutContainer ( Container parent )
{
Insets insets = parent.getInsets ();
for ( Component component : parent.getComponents () )
{
if ( !special.contains ( component ) )
{
component.setBounds ( insets.left, insets.top,
parent.getWidth () - insets.left - insets.right,
parent.getHeight () - insets.top - insets.bottom );
}
else
{
Dimension ps = component.getPreferredSize ();
component.setBounds ( parent.getWidth () - insets.right - 2 - ps.width,
insets.top + 2, ps.width, ps.height );
}
}
}
} );
final JTabbedPane tabbedPane = new JTabbedPane ();
tabbedPane.addTab ( "Tab1", new JLabel () );
tabbedPane.addTab ( "Tab2", new JLabel () );
tabbedPane.addTab ( "Tab3", new JLabel () );
frame.add ( tabbedPane );
final JLabel label = new JLabel ( "Close X" );
label.addMouseListener ( new MouseAdapter ()
{
public void mousePressed ( MouseEvent e )
{
System.exit ( 0 );
}
} );
frame.add ( label, "special", 0 );
frame.setSize ( 200, 150 );
frame.setLocationRelativeTo ( null );
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
frame.setVisible ( true );
}
这将在任何地方工作,没有任何问题。请注意,标签将始终位于右上角,并且不会在其他 OS LaF(如 Mac OS laf)上定位自身(除非您修改代码以支持更多“功能”),其中选项卡可能位于中间。如果标签与标签交叉,它也会被绘制在标签上。
所以你会得到这样的东西:
无论如何,您可以轻松地修改应用到布局内的 JLabel 边界以制作一些侧间距等......
这可以TabbedPaneUI
通过扩展BasicTabbedPaneUI
或编写您自己的来完成MetalTabbedPaneUI
。但这将很难写。
我相信你想实现类似关闭按钮的东西(下面也适用于 JLabel)
或者
setLayout(null)
为组件的位置和大小提供硬编码值并JButton
添加JTabbedPane
或者
setMouseListener
在 JTabbedPane 上检查鼠标点击位置是否在按钮的范围内。当然 - 您需要实现按钮的视觉状态(按下、悬停等)或只是将事件传递给faked
JButton 实例。